gpt4 book ai didi

c# - 将 struct* 从 c# 传递到 c++ dll

转载 作者:搜寻专家 更新时间:2023-10-31 01:30:26 29 4
gpt4 key购买 nike

c++ dll中的struct是这样定义的:

struct WAVE_INFO {
int channel_num;
int audio_type;
char *wave_data;
int wave_length;
};

调用方式如下:

extern "C" STRUCTDLL_API int processStruct(WAVE_INFO *pIn, WAVE_INFO *pOut);

我的 C# 结构中的 wave_data 必须是 byte array (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;
}

我们不能在要编码的结构中使用 byte[]。相反,我们必须将数组声明为 IntPtr 并自行处理编码。最简洁的方法是声明 byte[] 数组并使用 GCHandle 固定它们。

导入的函数如下所示:

[DllImport(dllfilename, CallingConvention = CallingConvention.Cdecl)]
static extern int processStruct(ref WAVE_INFO infoIn, ref WAVE_INFO infoOut);

对函数的相当困惑的调用是这样的:

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();
}

我这里的假设是第一个参数用于输入,第二个参数用于输出。但是调用者有责任为输出结构分配 wave 数据数组。

我还假设了一个调用约定,但您必须检查 C++ 宏 STRUCTDLL_API 以确定真正的调用约定是什么。

关于c# - 将 struct* 从 c# 传递到 c++ dll,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47921321/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com