C# P/Invoke struct嵌套union的问题

新手上路,请多包涵

C++的结构体嵌套联合体

typedef union
{
    int int_value;
    double double_value;
    bool bool_value;
}DATA_TYPE;

typedef struct
{
    char name[128];
    char description[128];
    BP_DATA_TYPE high_bound;
    BP_DATA_TYPE low_bound;
    BP_DATA_TYPE change_bound;
    BP_DATA_TYPE value;
    time_t time;
    DWORD error_code;
}DATA;

我用C#转换为以下形式

[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
public struct DATA_TYPE
{
    [FieldOffset(0)]
    public int int_value;
    [FieldOffset(0)]
    public double double_value;        
    [FieldOffset(0)]
    [MarshalAs(UnmanagedType.I1)]
    public bool bool_value;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct DATA
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
    public string name;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
    public string description;
    public BP_DATA_TYPE high_bound;
    public BP_DATA_TYPE low_bound;
    public BP_DATA_TYPE change_bound;
    public BP_DATA_TYPE value;
    public long time;
    public uint error_code;
}

获取的DATA结构体其他数据都正常,联合体DATA_TYPE为double和bool也是正常的,就是DATA_TYPE为int的时候是错的,当DATA_TYPE int_value=0的时候是对的,int_value=-1的时候C#读过来变成了-255,int_value=1024的时候C#读过来又是对的。
请问C++里联合体内的int不是对应C#的int吗,不都是占4个字节的吗?

阅读 2.3k
1 个回答
新手上路,请多包涵

搞定了,网上搜到了一篇大神的文章知道咋回事了。http://qingchina.bokee.com/33...

[StructLayout(LayoutKind.Explicit)]
public struct DATA_TYPE
{    
    [FieldOffset(0)]
    public double double_value;        
    [FieldOffset(0)]
    [MarshalAs(UnmanagedType.I1)]
    public bool bool_value;
    [FieldOffset(0)]
    public int int_value;//位置改变以下就正常额
}

按照上面链接里大神的说法:“在编译器中使用内存对齐, 是为了提高程序的性能. 访问未对齐的内存, 处理器需要做两次的内存访问, 但是, 对齐的内存, 仅需一次. 因为编译器将struct与自然边界对象. 自然边界为偶数地址, 可以被4或8整除. 一个struct的成员字节跨越了自然边界数, 认为是未对齐, 如果没有跨越, 可以访问一次就能读取。以后在设计struct时, 就要struct的成员类型和位置多做一些思考了.”

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进