c++ dll中的struct是这样定义的:
struct WAVE_INFO {
int channel_num;
int audio_type;
char *wave_data;
int wave_length;
};
Run Code Online (Sandbox Code Playgroud)
和这样的调用方法:
extern "C" STRUCTDLL_API int processStruct(WAVE_INFO *pIn, WAVE_INFO *pOut);
Run Code Online (Sandbox Code Playgroud)
我的 c# 结构中的wave_data必须是字节数组 (byte[])****,而不是 char[] 或 string。我应该如何在调用 dll 的 c# 中定义结构和方法?而且 wave_date 的长度是固定的,比如 100。
首先,我会说 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;
}
Run Code Online (Sandbox Code Playgroud)
我们不能byte[]在要编组的结构中使用。相反,我们必须将数组声明为IntPtr并自己处理编组。最简洁的方法是声明byte[]数组并使用GCHandle.
导入的函数如下所示:
[DllImport(dllfilename, CallingConvention = CallingConvention.Cdecl)]
static extern int processStruct(ref WAVE_INFO infoIn, ref WAVE_INFO infoOut);
Run Code Online (Sandbox Code Playgroud)
对函数的相当混乱的调用是这样的:
var dataIn = new byte[256];
// populate the input data array
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);
// dataOut should have been populated by processStruct
}
finally
{
dataOutHandle.Free();
}
}
finally
{
dataInHandle.Free();
}
Run Code Online (Sandbox Code Playgroud)
我的假设是第一个参数用于输入,第二个参数用于输出。但是调用者有责任为输出结构分配波形数据数组。
我还假设了调用约定,但是您必须检查 C++ 宏STRUCTDLL_API以确定真正的调用约定是什么。
| 归档时间: |
|
| 查看次数: |
5276 次 |
| 最近记录: |