CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3
  1. #1
    Join Date
    Apr 2007
    Posts
    7

    c# - passing an array of structs to a native DLL

    Hi all,

    I've been looking for some assistance on this all day with no luck, so any pointers would be helpful.

    struct SID_SEARCH_RESULT_DATA
    {
    ULONG ulFieldID;
    USHORT usFieldLength;
    char szFieldData[FIELD_LENGTH];
    };

    I want to pass this from a c# app into an unmanaged c++ dll and populate it. I've tried a couple of things but with no joy - can anyone give me an idea of the c++ exported method signature and the c# extern method declaration required to pass an array of this struct and populate it?

    The main complication is that I won't know how many results I will have up front, so I need to be able to assign sufficient memory on the c++ dll side.

    Any help would be hugely appreciated.

    Thanks , Lee.

    Edit: The C++ dll is not a COM object or anything similar, just a straight DLL. That's why I want to do this via p/invoke and some sort of marshalling wizardry. As you may be able to tell, this has landed on my desk with an urgent sticker on it and I'm new to c# & .NET, so I just need to get it working.
    Last edited by Azrael_666; April 30th, 2007 at 07:19 AM.

  2. #2
    Join Date
    Nov 2002
    Location
    Baby Land
    Posts
    646

    Re: c# - passing an array of structs to a native DLL

    I don't have visual studio handy so this might not 100% correct
    PHP Code:
    [StructLayout(LayoutKind.Sequential)]
    public 
    struct SID_SEARCH_RESULT_DATA
    {
         public 
    ulong ulFieldID;
         public 
    ushort usFieldLength;
         [
    MarshalAs(UnmanagedType.ByValTStrSizeConst=FIELD_LENGTH)]
         public 
    string szFieldData;


  3. #3
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940

    Re: c# - passing an array of structs to a native DLL

    Firstly, don't get mixed up with LONGs in C++ (which are 32-bits in size) and longs in C# (which are 64-bits in size).

    I'd set the charset too otherwise ByValTStr won't know what the character size is.

    Code:
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct SID_SEARCH_RESULT_DATA
    {
        public uint ulFieldID;
        public ushort usFieldLength;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
        public string szFieldData;
    }
    Secondly, to pass an array I'd do something like :

    Code:
    // c++
    void MyFunction(SID_SEARCH_RESULT_DATA *paData, int nArraySize)
    {
        for (int nIndex = 0; Index < nArraySize; nIndex += 1)
        {
            const SID_SEARCH_RESULT_DATA &rData = paData[nIndex];
            // etc
        }
    }
    I'd personally do my own marshalling to pass the array otherwise p/invoke will make a copy of the whole array e.g.

    Code:
    // C#
    using System.Runtime.InteropServices;
    
    public class Example
    {
        [DllImport("MyDll.dll")]
        static private extern void MyFunction(IntPtr pArray, int size);
    
        static public void MyFunction(SID_SEARCH_RESULT_DATA [] data)
        {
            GCHandle pData = GCHandle.Alloc(data, GCHandleType.Pinned);
            MyFunction(pData.AddrOfPinnedObject(), data.Length);
            pData.Free();
        }
    }
    You can't hold the pointer to the array for longer than the method call (e.g. by storing it in a member variable or the like) using this because the array is unpinned on exit. If you want the array to persist in the dll for longer than the call then you'll have to copy the array in the C++ method.

    Darwen.
    Last edited by darwen; May 1st, 2007 at 01:54 AM.
    www.pinvoker.com - PInvoker - the .NET PInvoke Interface Exporter for C++ Dlls.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured