我完全不知道如何使用数组参数调用本机dll中的函数。
示例:
该函数在C#项目中定义为:
[DllImport("Project2.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
static extern void modifyArray([MarshalAs(UnmanagedType.LPArray)] int[] x, int len);
函数调用是:
modifyArray(arr, 3)
其中arr = {4,5,6}
本机C ++函数定义如下:
extern "C" _declspec(dllexport) void modifyArray(int* x,int len)
{
int arr[] = {1,2,3};
x = arr;
}
为什么在C#项目中,数组在函数调用后没有指向新数组?它仍然是{4,5,6}。
我试过这个但是失败了
[DllImport("Project2.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
static extern void modifyArray([In,Out] int[] x, int len);
每当我尝试使用指针修改传递给这些函数的参数时,此pinvoke就会失败。否则,我成功传递了原生dll排序函数的ref数组参数,其中没有指针更改为新创建的类型。
答案 0 :(得分:2)
您的C ++代码已损坏。调用者分配数组,然后被调用者填充它。像这样:
extern "C" _declspec(dllexport) void modifyArray(int* x, int len)
{
for (int i=0; i<len; i++)
x[i] = i;
}
就您的p / invoke呼叫而言,SetLastError
不应该是true
。该函数未调用SetLastError
。它应该是:
[DllImport("Project2.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void modifyArray(int[] x, int len);
答案 1 :(得分:1)
这与PInvoke无关,这只是一个普通的旧C问题。如果您从C
调用modifyArray
,则会遇到完全相同的问题
int* pArray = NULL;
modifyArray(pArray, len);
pArray == NULL; // true!
在modifyArray
中,您正试图更改x
指向的位置。调用函数将无法看到此更改,因为指针是按值传递的。为了改变它所指向的位置,你需要传递一个双指针
void modifyArray(int** x, int len) {
*x = ...;
}
请注意,您当前正在尝试返回堆栈分配的内存而不是堆分配的内存。这是不正确的,将导致问题