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

如何在C#中封送C++结构体并访问其填充数据?

解决C++ DLL结构体在C#中无法访问数据的问题

1. 先修正C++代码的笔误

原C结构体Info的成员是midcycle,但初始化函数里写的是lp->mycycle = NOES;,这是拼写错误,必须改为lp->midcycle = NOES;,否则C侧的初始化逻辑本身就不生效。

2. 在C#中正确映射C++类型

要访问C结构体数据,必须在C#中精准复刻C的类型定义,包括枚举、数组、结构体的内存布局:

2.1 映射枚举类型

C++的MYCYCLETYPE枚举直接对应C#的enum,确保枚举值和底层类型匹配:

public enum MYCYCLETYPE
{
    NOES = 0,
    LET = 1,
    WARN = 2,
    GRACE = 3,
    EXP = 4
}

2.2 映射自定义日期数组

C++的CusDate是长度为11的char数组(sizeof("2023-02-02")包含末尾的\0,共11个字符),在C#中用ByValTStr修饰字符串来对应:

// 对应C++的char[11]
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
public string sedate;

2.3 完整映射结构体SINFO

指定结构体的内存布局为顺序排列,字符集匹配C的ANSI char,成员顺序必须和C完全一致:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct SINFO
{
    public MYCYCLETYPE midcycle;
    public int type;
    public int porotype;
    public long sways;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
    public string sedate;
    public long days;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
    public string elate;
    public long edays;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
    public string edate;
    [MarshalAs(UnmanagedType.LPStr)]
    public string feature;
    [MarshalAs(UnmanagedType.LPStr)]
    public string ver;
    [MarshalAs(UnmanagedType.LPStr)]
    public string hid;
}
  • const char*类型对应C#的string,用LPStr标记为ANSI字符串指针;
  • 若C++使用了内存对齐指令(如#pragma pack(4)),需在StructLayout中添加Pack = 4参数。

3. 修正DllImport和调用逻辑

调整DllImport的字符集设置,确保结构体初始化后再传入:

[DllImport("abc.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern int Initialize(ref SINFO lp);

static void Main()
{
    // C#结构体是值类型,必须初始化后再传递
    SINFO mydata = new SINFO();
    int result = Initialize(ref mydata);

    // 现在可以直接访问结构体成员
    Console.WriteLine($"周期类型: {mydata.midcycle}");
    Console.WriteLine($"硬件ID: {mydata.hid}");
    Console.WriteLine($"起始日期: {mydata.sedate}");
    // 其他成员同理访问
}

额外注意事项

  • 若C++的long是32位(如32位系统或特定编译器),C#需用int代替long,因为C#的long是64位;
  • 若C++的const char*指向动态分配的内存,需确保DLL负责内存释放,或在C#中调用Marshal.FreeHGlobal手动释放(需确认内存分配方式)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 18:57:06