How do I marshal a pointer to an array of pointers to structures?

后端 未结 1 705
夕颜
夕颜 2020-12-16 18:07

I have a C function with the following signature:

int my_function(int n, struct player **players)

players is a pointer to an a

相关标签:
1条回答
  • 2020-12-16 18:39

    I believe you'll have to do some of the marshaling manually. The function declaration should look like this:

    [DllImport("mylibary.dll")]
    private static extern int my_function(int n, IntPtr players);
    

    We'll need to allocate some native memory and marshal the structures to it before passing it in to the native function:

    private static void CallFunction(Player[] players)
    {
        var allocatedMemory = new List<IntPtr>();
    
        int intPtrSize = Marshal.SizeOf(typeof(IntPtr));
        IntPtr nativeArray = Marshal.AllocHGlobal(intPtrSize * players.Length);
        for (int i = 0; i < players.Length; i++)
        {
            IntPtr nativePlayer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Player)));
            allocatedMemory.Add(nativePlayer);
            Marshal.StructureToPtr(players[i], nativePlayer, false);
    
            Marshal.WriteIntPtr(nativeArray, i * intPtrSize, nativePlayer);
        }
    
        my_function(players.Length, nativeArray);
    
        Marshal.FreeHGlobal(nativeArray);
    
        foreach (IntPtr ptr in allocatedMemory)
        {
            Marshal.FreeHGlobal(ptr);
        }
    }
    

    If your native function is going to hold on to and re-use these memory locations, this won't work. If this is the case, either hold off on freeing the memory until you think it's not being used anymore or in the native method copy the data passed in and let the managed side clean up its memory immediately after the call.

    0 讨论(0)
提交回复
热议问题