Search code examples
c#c++dllimportmanageddllexport

How to wrap two unmanaged C++ functions into two managed C# functions?


I've got two unmanaged C++ functions, Compress and Decompress. The arguments and returns go as followed:

unsigned char* Compress (unsigned char*,int)

unsigned char* Decompress (unsigned char*,int)

Where all uchars are arrays of uchars.

Could someone please help me lay out a way to convert these into managed C# code using the Byte[] array instead of unsigned char*? Thank you very much!


Solution

  • You should be able to pass the unsigned char* parameter in as a byte[] and standard P/Invoke marshaller should handle that. You will have to marshal the output unsigned char* yourself, but that should just be a call to Marshall.Copy(). See below for an example of what I think will work.

    Two big questions:

    1. How does the caller know the size of data stored in the return unsigned char* buffer?
    2. How is the memory allocated for the return unsigned char* buffer? Do you have to free it and how will you free it from C# if you need to?

    Sample:

        [DllImport("Name.dll")]
        private static extern IntPtr Compress([MarshalAs(UnmanagedType.LPArray)]byte[] buffer, int size);
    
        [DllImport("Name.dll")]
        private static extern IntPtr Decompress([MarshalAs(UnmanagedType.LPArray)]byte[] buffer, int size);
    
        public static byte[] Compress(byte[] buffer) {
            IntPtr output = Compress(buffer, buffer.Length);
            /* Does output need to be freed? */
            byte[] outputBuffer = new byte[/*some size?*/];
            Marshal.Copy(output, outputBuffer, 0, outputBuffer.Length);
            return outputBuffer;
        }
    
        public static byte[] Decompress(byte[] buffer) {
            IntPtr output = Decompress(buffer, buffer.Length);
            /* Does output need to be freed? */
            byte[] outputBuffer = new byte[/*some size?*/];
            Marshal.Copy(output, outputBuffer, 0, outputBuffer.Length);
            return outputBuffer;
        }