user1005448
user1005448

Reputation: 637

C# p/invoke C method returning a byte*

I got a C dll where one of the functions has the following signature:

DLLExport byte* DecodeData(CDecoderApp* decoderApp, HWND handle, byte* data, int length, int* frameLength, int* waveDataLength, int* decodedFrameSize, int* channels, int* frequency)

I need to p/invoke this method and tried the following:

[DllImport("Decoder.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern byte[] DecodeData(IntPtr decoderApp, IntPtr handle, byte[] data, int length, out int frameLength, out int waveDataLength, out int decodedFrameSize, out int channels, out int frequency);

Which doesn't work as I guess that c# doesn't know the size of the byte array.

How should I solve this so I can get the returned byte array ?

Upvotes: 1

Views: 2415

Answers (1)

David Heffernan
David Heffernan

Reputation: 613053

The marshaller cannot, as you suspect, marshal a return value of type byte[]. You will need to do the marshalling yourself. Change the return value to be of type IntPtr:

[DllImport("Decoder.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr DecodeData(
    IntPtr decoderApp, 
    IntPtr handle, 
    byte[] data, 
    int length, 
    out int frameLength, 
    out int waveDataLength, 
    out int decodedFrameSize, 
    out int channels, 
    out int frequency
);

Call the function like this:

IntPtr decodedDataPtr = DecodeData(...);

Check for errors:

if (decodedDataPtr == IntPtr.Zero)
    // handle error

Presumably one of the parameters, perhaps waveDataLength contains the length of the byte array that is returned:

byte[] decodedData = new byte[waveDataLength];
Marshal.Copy(decodedDataPtr, decodedData, 0, waveDataLength);

Of course, now you are left holding a pointer to memory that the unmanaged code allocated. You will need to find a way to deallocate that memory. Perhaps the memory is allocated on a shared heap. Perhaps the unmanaged code exports a deallocator. But with the information that we have, we cannot tell you precisely how to deallocate it.

Upvotes: 1

Related Questions