用PInvoke返回一个包含char []的结构数组
问题描述:
我有一个从PInvoke返回的结构数组,如果结构只包含int或float,但它返回数组,但是当我尝试返回数组char它开始变得凌乱,我试图返回一个IntPtr,但那并没有成功。任何想法如何我可以得到这个工作?用PInvoke返回一个包含char []的结构数组
C代码
struct return_part {
int partid;
int numcomp;
int parttype;
char partname[100];
};
extern int return_parts(return_part ** array, int * arraySizeInElements) {
int partcount = 0;
struct list_part *currentnode;
currentnode = head;
struct section_list *section;
struct return_part *temppart;
while (currentnode != NULL) {
partcount++;
currentnode = currentnode->next;
}
currentnode = head;
*arraySizeInElements = partcount;
int bytesToAlloc = sizeof(return_part) * (*arraySizeInElements);
return_part * a = static_cast<return_part *>(CoTaskMemAlloc(bytesToAlloc));
*array = a;
int q = 0;
while (currentnode != NULL) {
struct return_part tmp;
tmp.partid = currentnode->partid;
tmp.numcomp = currentnode->numcomp;
strcpy(tmp.partname, currentnode->partname);
tmp.parttype = currentnode->parttype;
a[q] = tmp;
q++;
currentnode = currentnode->next;
}
return 0;
}
C#代码
[StructLayout(LayoutKind.Sequential)]
public struct return_part {
public int partid;
public int numcomp;
public int parttype;
public char partname;
};
internal static class UnsafeNativeMethods
{
[DllImport(_dllLocation, CallingConvention = CallingConvention.Cdecl)]
public static extern int return_parts([MarshalAs(UnmanagedType.LPArray,
SizeParamIndex = 1)] out return_part[] array, out int arraySizeInElements);
}
public static ReturnPoint[] getpoints(int partid) {
return_parts[] parts;
int size;
int result = UnsafeNativeMethods.return_parts(out parts, out size)
}
答
非托管代码的字符数组只是一个字符串,所以您在这里有两个选项。你使用哪一个取决于你在实际需要使用字符数据时如何返回C#-land:
-
将它作为一个数组来编组。见this article用于嵌入到结构数组如何得到整理(编辑:这就需要将ByValArray,不LPArray我最初代表;感谢@Hans):
[StructLayout(LayoutKind.Sequential)] public struct return_part { public int partid; public int numcomp; public int parttype; [MarshalAs(UnmanagedType.ByValArray, SizeConst=100)] public char[] partname; };
-
元帅它作为一个字符串。有关如何编组结构中包含的字符串,请参阅this article。
[StructLayout(LayoutKind.Sequential)] public struct return_part { public int partid; public int numcomp; public int parttype; [MarshalAs(UnmanagedType.ByValTStr, SizeConst=100)] public string partname; };
答
在C#的一面,你的结构有一个字符作为零件名称。尝试使用任一:
char[] partname; //-- A character array
byte[] partname; //-- A byte array
string partname; //-- A string
我倾向于喜欢字符串,如果有效。该字节可能工作,因为C#中的字节与C中的字符更符合逻辑地排列。字符数组也可能工作,因为C#中的字符在逻辑上表示实际单个字符(预期用途),C实际上并不具有(缺少无符号整数类型)。
LPArray是不正确的,即它变成字符*,不是char []。第二个片段很好。 – 2012-01-06 15:55:52
第二个工作很好,谢谢。 – user978281 2012-01-06 19:55:48
我的错误,你是对的;数组/指针等价仅在函数参数中是真实的,而不是嵌入到结构中。编辑来解决这个问题。 – 2012-01-06 21:15:57