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

标签 c# c++ dll struct

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/

相关文章:

c# - 使用 Drive API 访问 Google Drive 电子表格

c++ - 从 C++ 中的函数传递和返回多维数组

c++ - 在 DLL 中转发导出函数的问题

c# - 添加 .dll 作为引用。无法理解错误消息

c# - 四舍五入到顶部 - C#

c# - 在 C# : "...could not find the object..." 中从 Excel 读取错误

c# - 在 C# 中模拟无限滚动以获取页面的完整 html

c++ - 将二进制字符串转换为 ASCII 字符串 (C++)

c++ - 是否有使用带有引用参数的可变参数的陷阱

c - 为什么 LIB 文件是具有这种口是心非性质的野兽?