我正试图按照this question
的回答我的结构在C
中看起来像这样typedef struct drive_info_t {
unsigned char drive_alias[32];
} drive_info_t;
我的功能在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#struct看起来像这样
[StructLayout(LayoutKind.Sequential)]
public struct drive_info_t
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] drive_alias;
}
我的C#函数声明如下所示
[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#这样的函数
IntPtr ptr_list_info = IntPtr.Zero;
IntPtr ptr_cnt = IntPtr.Zero;
ret = api.GetDriveInfoList(out ptr_list_info, out ptr_cnt);
我正在整理像这样的返回指针
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));
}
打印像这样的结构别名
for (uint i = 0; i < localStructs.Length; i++)
{
Console.WriteLine("list.alias - {0}", System.Text.Encoding.Default.GetString(localStructs[i].drive_alias));
}
谢谢你和我在一起..
这是我的输出在C#中的控制台应用程序上的样子。你可以看到本机C dll打印到控制台它的值,但我的编组在某处弄乱了:
======================== 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
我不知道这个垃圾文本和偏移的来源。
我负责.Net方面,其他团队成员可以根据需要更改本机C,但本机C更改需要跨平台OSX / Windows / Linux。
提前致谢。
答案 0 :(得分:1)
这是为什么参数类型没有定义接口的完美示例。考虑
this is a string
<<this>>
<<is>>
<<a>>
<<string>>
这可能是指向结构数组的指针。在这种情况下,可能是被调用者分配了数组。这就是为什么使用指向数组的指针而不是数组的原因。
或者它可能是struct的指针数组。这里数组将由调用者分配,结构可以由被调用者或调用者分配。我们没办法告诉你。
我们可以看出你的接口接受了一个指向struct的指针数组。看看这段代码:
drive_info_t **list
很明显list[i]->drive_alias
是一个指向struct的指针数组。
这告诉您代码错误。您使用了错误的模板,因为您错误地识别了语义。下一步是返回接口的文档和调用代码的任何示例,以准确了解语义是什么。谁分配和解除分配什么。
几乎可以肯定,你会使用list
来编组数组,但除此之外我们不可能说出会发生什么。我猜测调用者会分配结构但不依赖于猜测。阅读文档和示例调用代码。
除此之外,第二个参数应该是IntPtr[]
或者ref uint
,具体取决于函数的语义。再一次,这是我们无法解决的问题。