C#p / invoke C方法返回一个字节*

时间:2015-11-19 14:28:21

标签: c# pinvoke

我有一个C dll,其中一个函数具有以下签名:

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

我需要p / invoke这个方法并尝试以下方法:

[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);

哪个不起作用,因为我猜c#不知道字节数组的大小。

我应该如何解决这个问题,以便获得返回的字节数组?

1 个答案:

答案 0 :(得分:1)

正如您所怀疑的那样,编组员不能编组byte[]类型的返回值。您需要自己进行编组。将返回值更改为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
);

像这样调用函数:

IntPtr decodedDataPtr = DecodeData(...);

检查错误:

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

大概是其中一个参数,也许waveDataLength包含返回的字节数组的长度:

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

当然,现在你要保留一个指向非托管代码分配的内存的指针。您需要找到一种释放内存的方法。也许内存是在共享堆上分配的。也许非托管代码导出deallocator。但是根据我们掌握的信息,我们无法准确地告诉您如何解除分配。