首先,我想说C++结构声明不正确。有效载荷是二进制数据,因此数组应该是unsigned char*
而不是char*
。
撇开这个问题,由于数组的存在,这个结构体在编组时有点棘手。大致上可以这样做:
[StructLayout(LayoutKind.Sequential)]
struct WAVE_INFO
{
public int channel_num;
public int audio_type;
public IntPtr wave_data;
public int wave_length;
}
我们不能在要被marshalled的结构体中使用byte[]
。相反,我们必须将数组声明为IntPtr
并自己处理marshalling。最清晰的方法是声明byte[]
数组并使用GCHandle
进行固定。
导入的函数看起来像这样:
[DllImport(dllfilename, CallingConvention = CallingConvention.Cdecl)]
static extern int processStruct(ref WAVE_INFO infoIn, ref WAVE_INFO infoOut)
而比较混乱的函数调用如下:
var dataIn = new byte[256];
var dataOut = new byte[256];
GCHandle dataInHandle = GCHandle.Alloc(dataIn, GCHandleType.Pinned);
try
{
GCHandle dataOutHandle = GCHandle.Alloc(dataOut, GCHandleType.Pinned);
try
{
WAVE_INFO infoIn;
infoIn.audio_type = 1;
infoIn.channel_num = 2;
infoIn.wave_data = dataInHandle.AddrOfPinnedObject();
infoIn.wave_length = dataIn.Length;
WAVE_INFO infoOut = new WAVE_INFO();
infoOut.wave_data = dataOutHandle.AddrOfPinnedObject();
infoOut.wave_length = dataOut.Length;
int retval = processStruct(ref infoIn, ref infoOut);
}
finally
{
dataOutHandle.Free();
}
}
finally
{
dataInHandle.Free();
}
我在这里的假设是第一个参数用于输入,第二个参数用于输出。但是,调用方需要为输出结构分配波形数据数组。
我还假设了一种调用约定,但是您需要检查C++宏STRUCTDLL_API
以确定真正的调用约定。