如何编组指向结构指针数组的指针?

时间:2010-03-26 21:56:05

标签: c# .net interop pinvoke marshalling

我有一个带有以下签名的C函数:

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

players是指向struct player个对象的指针数组的指针。 n是数组中指针的数量。该函数不修改数组也不修改结构的内容,并且在返回后不保留任何指针。

我尝试了以下内容:

[DllImport("mylibary.dll")]
static extern int my_function(int n, 
    [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] 
     player_in []players);

但是,它将数据编组为指向结构数组的指针,而不是指向结构指针数组的指针。

1 个答案:

答案 0 :(得分:11)

我相信你必须手动完成一些编组工作。函数声明应如下所示:

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

在将结构传递给本机函数之前,我们需要分配一些本机内存并编组结构:

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);
    }
}

如果您的本机功能将继续并重新使用这些内存位置,则无法使用。如果是这种情况,请暂停释放内存,直到您认为它不再被使用,或者在本机方法中复制传入的数据并让管理方在调用后立即清理其内存。