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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…