使用数组参数来固定本机函数

时间:2014-01-03 18:00:29

标签: c# arrays pinvoke

我完全不知道如何使用数组参数调用本机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数组参数,其中没有指针更改为新创建的类型。

2 个答案:

答案 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 = ...;
}

请注意,您当前正在尝试返回堆栈分配的内存而不是堆分配的内存。这是不正确的,将导致问题