c# 中的联合与 StructLayout

Posted

技术标签:

【中文标题】c# 中的联合与 StructLayout【英文标题】:Union in c# with StructLayout 【发布时间】:2012-05-05 05:04:56 【问题描述】:

我有多个结构都以标头结构开头。像这样

public struct BaseProtocol 
    public Header header;
    public Footer footer;
;

标题是

public struct Header 
    public Byte start;
    public Byte group;
    public Byte dest;
    public Byte source;
    public Byte code;
    public Byte status;
;

现在的问题是我需要将它们与 Byte[] 联合起来。我用这个试过了

[StructLayout( LayoutKind.Explicit, Size=255 )]
public struct RecBuffer 

    [FieldOffset( 0 )]
    public Header header;

    [FieldOffset( 0 )]
    [MarshalAs( UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = 255 )]
    public Byte[] buffer;
;

当我用数据填充缓冲区时,我无法从标题中获取数据。如何使 c# 与 c++ 中的 union 一样?

【问题讨论】:

“我无法从标题中获取数据”是什么意思?你有例外吗?你得到不正确的数据吗?您尝试从哪个字段访问标头,headerbuffer 字段? 我把它放在缓冲区中: 0xe0 0x11 0x11 0x00 0x05 0x00 但是当我这样做时,recBuffer.header.start 是 0x00 而不是 0xe0。 【参考方案1】:

Byte[] 是引用类型字段,不能与值类型字段重叠。您需要一个固定大小的缓冲区,并且需要使用/unsafe 对其进行编译。像这样:

[StructLayout(LayoutKind.Explicit, Size = 255)]
public unsafe struct RecBuffer


    [FieldOffset(0)]
    public long header;

    [FieldOffset(0)]
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = 255)]
    public fixed Byte buffer[255];
;

【讨论】:

以上是关于c# 中的联合与 StructLayout的主要内容,如果未能解决你的问题,请参考以下文章

Marshal Union(C) 与包含 C# 中的数组的结构

与 C# 中的数组缓冲区联合

C#中的可区分联合

项目实战 | c#与VisionPro联合编程添加编辑图像处理程序窗口

项目实战 | c#与VisionPro联合编程添加通信功能

Halcon与C#联合编程:使用S7协议实现机器视觉上位机与西门子PLC联动