Search code examples
c#arrayspinvoke

Pinvoking a native function with array arguments


I am completely confused with how to go about calling functions in native dll with array arguments.

Example:

The function is defined in the C# project as:

[DllImport("Project2.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
static extern void modifyArray([MarshalAs(UnmanagedType.LPArray)] int[] x, int len);

And the function call is:

modifyArray(arr, 3)

where arr = {4,5,6}

The native C++ function definition is as follows:

extern "C" _declspec(dllexport) void modifyArray(int* x,int len)
{   
        int arr[] = {1,2,3};
        x = arr;
}

Why in the C# project, the array is not pointing to the new array after the function call? It still remains {4,5,6}.

I tried this to but failed

[DllImport("Project2.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
static extern void modifyArray([In,Out] int[] x, int len);

This pinvoke fails whenever I try modifying arguments passed to these functions using pointers. Otherwise, I have had success passing ref array arguments for native dll sort functions where there is no pointer changes to newly created types.


Solution

  • Your C++ code is broken. The caller allocates the array, and the callee populates it. Like this:

    extern "C" _declspec(dllexport) void modifyArray(int* x, int len)
    {   
        for (int i=0; i<len; i++)
            x[i] = i;
    }
    

    As far as your p/invoke call goes, SetLastError should not be true. The function is not calling SetLastError. It should be:

    [DllImport("Project2.dll", CallingConvention = CallingConvention.Cdecl)]
    static extern void modifyArray(int[] x, int len);