Get an array of structures from native dll to c# application

后端 未结 1 1332
醉酒成梦
醉酒成梦 2021-01-02 06:20

I have a C# .NET 2.0 CF project where I need to invoke a method in a native C++ DLL. This native method returns an array of type TableEntry. At the time the nat

相关标签:
1条回答
  • 2021-01-02 07:15

    When marshalling an array of unknown size from native to managed I find the best strategy is as follows

    • Type the array to IntPtr in managed code
    • Have the native code return both the array and a size parameter.
    • Manually marshal the data from IntPtr to the custom struct on the managed side.

    As such I would make the following changes to your code.

    Native:

    extern "C" __declspec(dllexport) bool GetTable( TABLE_ENTRY** table, __int32* pSize )
    {
        *table = &global_dll_table.front();
        *pSize = static_cast<int32>(global_dll_table.size());
        return true;
    }
    

    Managed:

    [DllImport("MyDll.dll", 
        CallingConvention = CallingConvention.Winapi, 
        CharSet = CharSet.Auto)]
    [return: MarshalAs(UnmanagedType.I1)]
    public static extern bool GetTable(out IntPtr arrayPtr, out int size);
    
    public static List<TableEntry> GetTable() {
      var arrayValue = IntPtr.Zero;
      var size = 0;
      var list = new List<TableEntry>();
    
      if ( !GetTable(out arrayValue, out size)) {
        return list; 
      }
    
      var tableEntrySize = Marshal.SizeOf(typeof(TableEntry));
      for ( var i = 0; i < size; i++) {  
        var cur = (TableEntry)Marshal.PtrToStructure(arrayValue, typeof(TableEntry));
        list.Add(cur);
        arrayValue = new IntPtr(arrayValue.ToInt32() + tableEntrySize);
      }
      return list;
    }
    
    0 讨论(0)
提交回复
热议问题