C#学习教程:从C#调用接受调用者分配的结构数组的C函数*A;字符fn[MAX_FN];无符号长l;无符号长o;};我想从C#调用以下函数:extern"C"intfunc(inthandle,int*numEntries,XYZ*xyzTbl);其中xyzTbl由调用者分配的大小为numEntires的XYZ数组给出我定义了以下C#结构:[StructLayoutAttribute(Sequential,CharSet=CharSet.Ansi)][MarshalAsAttribute(UnmanagedType.ByValTStr,SizeConst=128)]publicstringfn;公共单位l;公共单位o;}和方法:[DllImport(@"xyzdll.dll",CallingConvention=CallingConvention.Cdecl)]publicstaticexternInt32func(Int32handle,refInt32nuntries,[MarshalAs(UnmanagedType.LPArray)]XYZ[]arr);然后我尝试调用函数:XYZxyz=newXYZ[numEntries];对于(...)xyz[i]=newXYZ();func(句柄,numEntries,xyz);当然它不起作用。有人可以阐明我做错了什么吗?[StructLayoutAttribute(Sequential,CharSet=CharSet.Ansi)]publicstructXYZ{publicSystem.IntPtrrva;[MarshalAsAttribute(UnmanagedType.ByValTStr,SizeConst=128)]publicstringfn;公共单位l;公共单位o;应该是ulong吗?另外,MAX_FN是128吗?XYZxyz=新的XYZ[条目数];对于(...)xyz[i]=newXYZ();XYZ是一个值类型(struct),所以这里的第二行是多余的(structs总是被初始化)[DllImport(@"xyzdll.dll",CallingConvention=CallingConvention.Cdecl)]publicstaticexternInt32func(Int32handle,refInt32numntries,[MarshalAs(UnmanagedType.LPArray)]XYZ[]arr);[MarshalAs(UnmanagedType.LPArray)]是多余的,编译器会将其视为结构数组。看看这个:MarshalC++structarrayintoC#,它可能有帮助。我会手动编组。首先,将xyzTbl设为IntPtr。[DllImport(@"xyzdll.dll",CallingConvention=CallingConvention.Cdecl)]publicstaticexternInt32func(Int32handle,refInt32numntries,IntPtrxyzTb);而不是像你正在做的那样分配XYZ数组-分配足够的非托管内存来存储表。IntPtrunmanaged=Marshal.AllocHGlobal(Marshal.SizeOf(typeof(XYZ))*numEntries);调用你的func(handle,refnumEntries,unmanaged);然后,工作是将非托管内存解组为托管类型。IntPtr[]entries=newIntPtr[numEntries];列表xyz=新列表();Marshal.Copy(unmanaged,entries,0,numEntries);foreach(条目中的IntPtr条目)xyz.Add(Marshal.PtrToStructure(entry,typeof(XYZ)));Marsha.FreeHGlobal(非托管);当你有一个托管结构时,我不相信你可以使用LPArray。只需将其取出并在需要时使用[In]和[Out]。IIRC,如果你使用LPArray,它会尝试将指针传递给第一个元素,这是非法的,因为该结构不可blittable。您需要完全删除[MarshalAs(...)]。编辑:我不记得了,但是您可能需要在传递字符串字段之前对其进行初始化……我会在有机会时检查一下。以上是C#学习教程:从C#调用C函数,函数接受调用者分配的结构体数组共享的所有内容。如果对大家有用,需要了解更多C#学习教程,希望大家多加关注——本文来自网络收藏,不代表立场,如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
