如何封送指向结构体指针数组的指针?

发布于 2024-08-26 22:36:06 字数 473 浏览 4 评论 0原文

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

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

players 是一个指向 structplayer 对象的指针数组的指针。 n 是数组中指针的数量。该函数不会修改数组或结构体的内容,并且返回后不保留任何指针。

我尝试了以下操作:

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

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

I have a C function with the following signature:

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

players is a pointer to an array of pointers to struct player objects. n is the number of pointers in the array. The function does not modify the array nor the contents of the structures, and it does not retain any pointers after returning.

I tried the following:

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

However, that marshals the data as a pointer to an array of structures, not a pointer to an array of pointers to structures.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

站稳脚跟 2024-09-02 22:36:06

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

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文