3
votes

I am using a pointer to a unsigned long array (manipulate data) then send it back to C#

in C#

[DllImport("some_dll.dll")]
private static extern uint[] func(uint[]x, uint[]y, uint[]z);

C header

_declspec(dllexport) unsigned long* _stdcall func(unsigned long[],
    unsigned long[],unsigned long[]);

error

MarshalDirectiveException
Cannot marshal 'return value': Invalid managed/unmanaged type combination

Kindly let me know what is causing the problem.

1
You should use a IntPtr as returned value, and then use Marshal.Copy to copy from IntPtr to uint[].Jigsore
There are a lot of problems with this function signature. How does the function know how many elements are in the arrays? How does the caller release the memory for the returned array? How does the caller know how large the returned array is? How does the caller know that the function failed? Questions you must answer before you can write a proper declaration for the function.Hans Passant

1 Answers

4
votes

The message means that the p/invoke marshaller isn't capable of marshalling that return value into a uint[].

As I see it you have the following options:

  1. Declare the C# function as returning IntPtr. Then on the managed side you need to copy the memory into a uint[] allocated in your C# code. You can use Marshal.Copy to do that. Somehow you'll need to find out the length of the array. You also need to handle deallocation. Your C# code cannot do that. So it will have to call another function in the native code and ask the native code to deallocate.
  2. Allocate the uint[] in the C# code before the call to your native code. Instead of using a function return value, you pass the uint[] as a parameter. This requires the calling code, the C# code, to know how big the array needs to be.

If you can choose option 2, it will result in simpler code on both sides of the interface. My guess is that the return array is the same length as the input arrays. In which case choose option 2.