C#向C传结构体引用时ZEN成员值不正确问题排查
问题根因
问题出在C# P/Invoke封送逻辑中,值类型和引用类型的传参语义不匹配:
- C端测试函数的入参是单级结构体指针,期望直接拿到结构体字段内存的首地址。
- 你定义的
MYARRAYSTRUCT是值类型struct,用ref关键字传参时,封送层直接传递结构体实例的实际内存首地址,完全匹配C端的单级指针要求,所以数据传递正常。 - 你定义的
ZEN是引用类型class,引用类型的变量本身存储的是指向托管堆上对象实例的指针。此时再加ref关键字传参,传递的是指向该对象引用的二级指针,和C端期望的单级结构体指针完全不匹配。C端拿到地址后按结构体布局读取时,实际读到的是托管引用的内存数据,不是你赋值的结构体字段,所以输出是随机乱码,每次运行结果都不固定。
修复方案
二选一即可:
- 方案1(和现有正常实现逻辑对齐,推荐):将
ZEN从引用类型class改为值类型struct,保留现有的[StructLayout(LayoutKind.Sequential)]、定长数组封送特性、ref传参写法即可,不需要调整其他逻辑。 - 方案2:保留
ZEN为class类型,删除对应DllImport函数参数前的ref关键字,直接传递类实例即可。
额外校验点:如果调整传参逻辑后仍有字段值错位,需要逐一核对字段类型长度匹配:C端
BYTE对应C#的byte(1字节),Windows x86环境下C编译的DWORD对应uint(4字节)、LONG对应int(4字节),不要错用为C#的long(8字节);同时可以显式给StructLayout特性添加Pack = 8参数,和C端x86默认的结构体对齐规则保持一致,避免对齐偏差导致的字段偏移错误。
内容的提问来源于stack exchange,提问作者of32 inc
相关产品推荐
相关产品推荐

