There are two things.
At first, the P / Invoke layer does not process reference parameters in C ++; it can only work with pointers. The last two parameters ( pOutputBuffer and uOutputSize ), in particular, are not guaranteed for the correct marshal.
I suggest you change your C ++ method declaration (or create a form wrapper):
extern "C" __declspec(dllexport) bool __stdcall CompressData( unsigned char* pInputData, unsigned int inSize, unsigned char** pOutputBuffer, unsigned int* uOutputSize)
However, the second problem arises because the P / Invoke layer also does not know how to redirect raw arrays (unlike, say, SAFEARRAY in COM, which knows about this size) that are allocated in unmanaged code .
This means that on the .NET side, you must marshal the created pointer, and then manually output the elements in the array (and also get rid of it if this is your responsibility, which it seems to have).
Your .NET declaration will look like this:
[System.Security.SuppressUnmanagedCodeSecurity] [DllImport(dllName)] public static extern bool CompressData(byte[] inputData, uint inputSize, ref IntPtr outputData, ref uint outputSize);
When you have outputData as IntPtr (this will indicate unmanaged memory), you can convert to an array of bytes by calling Copy in the Marshal class like this:
var bytes = new byte[(int) outputSize];
Please note that if your responsibility frees up memory, you can call the FreeCoTaskMem method:
Marshal.FreeCoTaskMem(outputData);
Of course, you can wrap this in something nicer, for example:
static byte[] CompressData(byte[] input, int size) { // The output buffer. IntPtr output = IntPtr.Zero; // Wrap in a try/finally, to make sure unmanaged array // is cleaned up. try { // Length. uint length = 0; // Make the call. CompressData(input, size, ref output, ref length); // Allocate the bytes. var bytes = new byte[(int) length)]; // Copy. Marshal.Copy(output, bytes, 0, bytes.Length); // Return the byte array. return bytes; } finally { // If the pointer is not zero, free. if (output != IntPtr.Zero) Marshal.FreeCoTaskMem(output); } }