C# p/invoke C 方法返回一个字节*
C# p/invoke C method returning a byte*
我得到了一个 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# 不知道字节数组的大小。
我应该如何解决这个问题才能得到返回的字节数组?
编组器不能像您怀疑的那样编组 return 类型 byte[]
的值。您将需要自己进行编组。将 return 值更改为 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
包含字节数组的长度,即returned:
byte[] decodedData = new byte[waveDataLength];
Marshal.Copy(decodedDataPtr, decodedData, 0, waveDataLength);
当然,现在您只剩下指向非托管代码分配的内存的指针。您将需要找到一种方法来释放该内存。也许内存是在共享堆上分配的。也许非托管代码导出一个释放器。但是根据我们掌握的信息,我们无法准确告诉您如何解除分配它。
我得到了一个 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# 不知道字节数组的大小。
我应该如何解决这个问题才能得到返回的字节数组?
编组器不能像您怀疑的那样编组 return 类型 byte[]
的值。您将需要自己进行编组。将 return 值更改为 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
包含字节数组的长度,即returned:
byte[] decodedData = new byte[waveDataLength];
Marshal.Copy(decodedDataPtr, decodedData, 0, waveDataLength);
当然,现在您只剩下指向非托管代码分配的内存的指针。您将需要找到一种方法来释放该内存。也许内存是在共享堆上分配的。也许非托管代码导出一个释放器。但是根据我们掌握的信息,我们无法准确告诉您如何解除分配它。