PInvoke的 - 从元帅指针结构的数组 [英] PInvoke - Marshal an array of structs from pointer

查看:109
本文介绍了PInvoke的 - 从元帅指针结构的数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图跟随答案在这个问题

我的结构看起来像在C

My struct looks like this in C

typedef struct drive_info_t {
    unsigned char drive_alias[32];
} drive_info_t;

我的功能看起来像在C

My function looks like this in C

unsigned int get_drive_info_list(drive_info_t **list, unsigned int *item_count) {
    //fill list in native C

    //print out in native C
    printf("list.alias - %s\r\n",list[i]->drive_alias);
}

我的C#结构看起来像这样

My C# struct looks like this

[StructLayout(LayoutKind.Sequential)]
public struct drive_info_t
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
    public byte[] drive_alias;
}

我的C#函数的声明看起来像这样

My C# function declaration looks like this

[DllImport("mydll.dll", EntryPoint = "get_drive_info_list", CallingConvention = CallingConvention.Cdecl)]
public static extern uint GetDriveInfoList(out System.IntPtr ptr_list_info, out System.IntPtr ptr_count);

我打电话C#函数像这样

I'm calling C# function like this

IntPtr ptr_list_info = IntPtr.Zero;
IntPtr ptr_cnt = IntPtr.Zero;

ret = api.GetDriveInfoList(out ptr_list_info, out ptr_cnt);

我编组返回的指针,这样

I'm marshaling the returned pointers like this

nAlloc = ptr_cnt.ToInt32();

int szStruct = Marshal.SizeOf(typeof(api.drive_info_t));
api.drive_info_t[] localStructs = new api.drive_info_t[nAlloc];

for (int i = 0; i < nAlloc; i++)
{
    localStructs[i] = (api.drive_info_t)Marshal.PtrToStructure(ptr_list_info, typeof(api.drive_info_t));
    ptr_list_info = new IntPtr(ptr_list_info.ToInt32() + (szStruct));
}

打印结构别名像这样

Printing the struct alias like this

for (uint i = 0; i < localStructs.Length; i++)
{    
    Console.WriteLine("list.alias - {0}", System.Text.Encoding.Default.GetString(localStructs[i].drive_alias));
}

感谢您与我住..

Thanks for staying with me..

这是我的输出看起来像在C#控制台应用程序。你可以看到本机C DLL印刷到它的价值控制台,但我的编组在某个地方搞乱了:

This is what my output looks like on a console application in C#. You can see the native C dll printing to the console it's values, but my marshaling is messing up somewhere:

======================== C values ============================
list.alias - drv1
list.alias - drv2
list.alias - drv3
list.alias - drv4
======================== C# values ============================
list.alias - drv1
list.alias - o£Q95drv2
list.alias -         o£Q95drv3
list.alias -                 o£Q95drv4

我不知道在哪里这个垃圾文字和偏移量是从哪里来的。

I have no clue where this garbage text and offset is coming from.

我负责的净面,根据需要如果需要其他团队成员可以改变原生C,但本地C的变化需要跨平台OSX / Windows / Linux版。

I'm responsible for the .Net side, other team members can change the native C as needed if required, but native C changes need to be cross-platform OSX/Windows/Linux.

先谢谢了。

推荐答案

这就是为什么类型的参数不定义接口的完美典范。考虑

This is a perfect example of why the types of the arguments do not define the interface. Consider

drive_info_t **list

这可以是一个指针结构的数组。在这种情况下,presumably阵列是由被叫方分配。这就是为什么使用指针数组,而不是一个数组。

This could be a pointer to an array of structs. In which case presumably the array is allocated by the callee. Which is why a pointer to array is used as opposed to an array.

或者,它可以是指针结构体的阵列。在这里,数组将被调用者分配和结构既可以由被叫方或号码来分配。没办法为我们讲述。

Or it could be an array of pointers to struct. Here the array would be allocated by caller and the structs could be allocated by either callee or caller. No way for us to tell.

我们可以看出,你的接口接受指针结构的阵列。看看这个code:

We can discern that your interface accepts an array of pointers to struct. Look at this code:

list[i]->drive_alias

很显然列表是指向结构的阵列。

这告诉你,你的code是错误的。你走错了模板,因为你误识别的语义。下一步是返回到文档接口以及任何调用例如code学习precisely的语义是什么。谁分配和释放的。

This tells you that your code is wrong. You have followed the wrong template because you mis-identified the semantics. Your next step is to return to the documentation for the interface and any example calling code to learn precisely what the semantics are. Who allocates and deallocated what.

几乎可以肯定你会使用 IntPtr的[] 当元帅的数组,但除此之外,它是不可能对我们说会发生什么。我猜想,来电分配结构,但不靠猜测。阅读文档和示例调用code。

Almost certainly you will use IntPtr[] to marshal the array but beyond that it is impossible for us to say what happens. I would guess that the caller allocates the structs but don't rely on guesswork. Read the documentation and example calling code.

除此之外,第二个参数应该是 REF UINT 或者出UINT 根据功能的语义。同样,在这个时候,我们不能工作了。

Beyond that the second argument should be ref uint or perhaps out uint depending on the semantics of the function. Again, that's something that we cannot work out.

这篇关于PInvoke的 - 从元帅指针结构的数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆