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


我有一个带有以下签名的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);

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


10303
2018-03-26 21:56


起源



答案:


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

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

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


11
2018-04-02 20:57