【问题标题】:How do I marshal a pointer to an array of pointers to structures?如何编组指向结构指针数组的指针?
【发布时间】:2011-02-01 09:22:59
【问题描述】:

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

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

【问题讨论】:

    标签: c# .net interop pinvoke marshalling


    【解决方案1】:

    我相信您必须手动进行一些编组。函数声明应如下所示:

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

    如果您的本机函数要保留并重新使用这些内存位置,这将不起作用。如果是这种情况,要么推迟释放内存,直到您认为它不再被使用,或者在本机方法中复制传入的数据并让托管方在调用后立即清理其内存。

    【讨论】:

      猜你喜欢
      • 2017-06-03
      • 1970-01-01
      • 1970-01-01
      • 2012-12-07
      • 2016-06-20
      • 1970-01-01
      相关资源
      最近更新 更多