You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#调用返回_DEVICE_INFO结构体的C++ DLL函数结果为空,求解决

C#调用C++ DLL结构体指针返回空的解决方案

核心问题分析

你的代码存在三个关键错误,导致无法正确获取设备信息:

  1. 函数签名不匹配:C++函数接收并返回结构体指针,但C#代码以值类型传递参数并返回值类型,封送层无法正确转换指针与值类型的映射。
  2. 缺少字符集指定:C++的TCHAR依赖字符集配置,未显式指定会导致字符串封送错误。
  3. 调用约定未显式声明:C++函数使用__stdcall,C#默认虽可能匹配,但显式声明可避免栈不平衡问题。

修正后的代码实现

1. 结构体定义(添加字符集)

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct _DEVICE_INFO
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    public string chDeviceName;
    public int nCommPort;
    public int nECGPos;
    public int nNumberOfChannel;
    public int nESUType;
    public int nTymestampType;
    public int nDeviceHandle;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
    public string chDeviceID;
}

若C++库使用ANSI字符集(TCHAR为char),将CharSet.Unicode改为CharSet.Ansi。

2. DLL导入函数定义(匹配指针与调用约定)

[DllImport(@"\BAlertSDK\ABM_Athena.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
static extern IntPtr GetDeviceInfoKeepConnection(ref _DEVICE_INFO deviceInfo);

用IntPtr接收C返回的结构体指针,用ref关键字传递结构体,确保C能修改传入的结构体内容。

3. 调用示例

void Test_Click()
{
    _DEVICE_INFO d = new _DEVICE_INFO();
    IntPtr resultPtr = GetDeviceInfoKeepConnection(ref d);
    
    // 检查返回指针是否有效(非空表示成功)
    if (resultPtr != IntPtr.Zero)
    {
        // 此时d已被C++函数填充,可直接使用
        Console.WriteLine($"设备名称:{d.chDeviceName}");
        Console.WriteLine("设备信息获取成功");
    }
    else
    {
        Console.WriteLine("设备信息获取失败");
    }
}

额外注意事项

  • 如果C++函数返回的是新分配的结构体内存(而非修改传入的结构体),需要手动封送指针到结构体,并调用DLL提供的内存释放函数(通常会有对应FreeDeviceInfo之类的函数),避免内存泄漏:
    // 假设存在释放函数
    [DllImport(@"\BAlertSDK\ABM_Athena.dll", CallingConvention = CallingConvention.StdCall)]
    static extern void FreeDeviceInfo(IntPtr deviceInfoPtr);
    
    // 调用示例
    IntPtr resultPtr = GetDeviceInfoKeepConnection(IntPtr.Zero); // 若参数可传空
    if (resultPtr != IntPtr.Zero)
    {
        _DEVICE_INFO deviceInfo = (_DEVICE_INFO)Marshal.PtrToStructure(resultPtr, typeof(_DEVICE_INFO));
        // 使用设备信息...
        FreeDeviceInfo(resultPtr); // 释放内存
    }
    

内容的提问来源于stack exchange,提问作者Jose Eduardo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 13:10:49