C#与C++交互编程结构体(struct)对齐问题

在C#和C++交互时,由于C#的bool类型占4字节而C++的bool占1字节,导致结构体在跨语言传递时出现数据错乱。通过在C#的bool成员上添加[MarshalAs(UnmanagedType.I1)]或[MarshalAs(UnmanagedType.U1)]属性,可以确保bool按1字节正确封送,从而解决这个问题。
摘要由CSDN通过智能技术生成

问题:C#调用C++库函数时,传入参数是结构体Struct(按照1字节对齐),调试时发现传入参数赋值正常,但是传入到C++函数内,参数的值不对了。

C++定义结构体

typedef struct A{
	int a;
	int b;
	bool c;
	int d;
} __attribute__((packed)) A;

#pragma pack(1)
typedef struct A{
	int a;
	int b;
	bool c;
	int d;
}A;

C#定义的结构体

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct A
    {
        public int a;
        public int b;
        public bool c;
        public int d;
    }

结论:在bool变量前加一个[MarshalAs (UnmanagedType.I1)]或[MarshalAs (UnmanagedType.U1)]属性。再次调试,C#传入C++函数的结构体参数正确了。

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct A
    {
        public int a;
        public int b;
        [MarshalAs (UnmanagedType.I1)]
        public bool c;
        public int d;
    }
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct A
    {
        public int a;
        public int b;
        [MarshalAs (UnmanagedType.U1)]
        public bool c;
        public int d;
    }

原因:C#中bool是int型的占4字节,而C/C++里面的bool是byte型的占1字节,导致虽然添加了pack=1的属性,但是当由托管内存(C#)向非托管内存(C/C++)封送的时候是按照4字节来的,而原生C++代码是按照1字节来读取的。

先来看一下官方文档对C#中bool的解释Boolean 结构 (System) | Microsoft Learn

 以及对类型UnmanagedType的解释UnmanagedType 枚举 (System.Runtime.InteropServices) | Microsoft Learn

 

扩展:

StructLayoutAttribute 类 (System.Runtime.InteropServices) | Microsoft Learn

StructLayoutAttribute.Pack 字段 (System.Runtime.InteropServices) | Microsoft Learn

StructLayoutAttribute.CharSet 字段 (System.Runtime.InteropServices) | Microsoft Learn

参考:

c# - StructLayout Pack=1 不适用于 bool? - IT工具网 (coder.work)

Boolean 结构 (System) | Microsoft Learn

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值