Passing a byte array between C ++ and C # ByRef raises an AccessViolationException

I am trying to create a win32 dll that provides some functions that are called in c # as follows

__declspec(dllexport) int GetData(unsigned char* *data, int* size) { try { int tlen = 3; unsigned char* tchr = new unsigned char[5]; tchr[0] = 'a'; tchr[1] = 'b'; tchr[2] = 'c'; *size = tlen; *data = tchr; return 1; } catch (char *p) { return 0; } } 

And on the C # side

 [DllImport("MyDll.dll")] static extern int GetData(ref byte[] data, ref int size); static void Main() { try { int hr = 0; byte[] gData = null; int gSize = 0; hr = GetData(ref gData, ref gSize); Console.WriteLine(gSize); for (int i = 0; i < gSize; i++) Console.WriteLine((char)gData[i]); } catch (Exception p) { Console.WriteLine(p.ToString()); } } 

When I run the C # code, an AccessViolationException occurs in the GetData function, which is an exception sign in C ++ code, however, after the code snippet, C ++ works fine without any errors.

 int _tmain(int argc, _TCHAR* argv[]) { unsigned char* data = NULL; int size = NULL; GetData(&data, &size); printf("%d", size); for (int i = 0; i < size; i++) printf("%c,", data[i]); return 0; } 

If you compare the C # main and C ++ _tmain , they are almost the same, so can I be wrong?

+6
source share
1 answer

You return the array allocated by calling C ++ new, and hope that the marshaler turns it into a C # [] byte. It will not happen.

You will need to pass the pointer by reference, and then marshal it manually. Your p / invoke should look like this:

 [DllImport("MyDll.dll")] static extern int GetData(out IntPtr data, out int size); 

When a function returns data, it will point to an array, and you can read the contents using the Marshall class. I think you would copy it to a new byte array .

 var arr = new byte[size]; Marshal.Copy(data, arr, 0, size); 

Some other points:

  • Calling agreements do not match. The native side is cdecl, and the managed side is stdcall.
  • You will need to export the deallocator to remove the memory returned by the built-in function. Consider a redesign where the caller allocates a buffer.
+10
source

All Articles