如何在C#中调用C++ DLL函数填充无符号整数数组?
解决C#调用C++ DLL填充整数数组的问题
嘿,作为C#新手遇到这个P/Invoke的问题太正常了,我来帮你捋清楚怎么改!
首先咱们先揪出问题根源:你原来的C#函数声明里用了ref uint ids,但C++里的unsigned int* ids是数组指针,不是单个uint的引用,所以编译器才会报错说没法把uint[]转成ref uint。
正确的DllImport声明
C#里调用C的数组参数时,直接用uint[]就可以了(P/Invoke会自动把它 marshaling 成C的数组指针),同时要注意调用约定——C++默认是cdecl,必须在DllImport里明确指定,不然很容易出现栈溢出的问题。
正确的函数声明应该是这样的:
[DllImport("MyFunc.dll", CallingConvention = CallingConvention.Cdecl)] private static extern uint MyFunc(uint[] ids, ref uint size);
如果想更明确标注数组类型,也可以加上MarshalAs属性(其实不加也没问题,因为数组默认就是按LPArray处理的):
[DllImport("MyFunc.dll", CallingConvention = CallingConvention.Cdecl)] private static extern uint MyFunc( [MarshalAs(UnmanagedType.LPArray)] uint[] ids, ref uint size);
正确的调用示例
现在你就可以正常调用函数填充数组了,和你原来的写法几乎一样,只是去掉了数组参数前的ref修饰:
// 初始化一个长度为2000的数组 uint[] myIds = new uint[2000]; // 传入数组的初始长度 uint size = (uint)myIds.Length; // 调用DLL函数填充数组 uint status = MyFunc(myIds, ref size); // 注意:调用后size的值会被DLL修改为实际填充的元素数量 // 比如如果DLL只填充了1500个元素,size就会变成1500
补充说明
- 调用约定一定要对应:如果你的C++函数是用
__stdcall声明的(比如Windows API常用的约定),就把CallingConvention改成CallingConvention.StdCall。 - 确保DLL路径正确:如果DLL不在程序运行目录下,要么把DLL复制过去,要么在
DllImport里写完整路径。
内容的提问来源于stack exchange,提问作者bioan
相关产品推荐
相关产品推荐

