【问题标题】:C++ struct/union into C# structC++ 结构/联合到 C# 结构
【发布时间】:2017-04-29 01:01:10
【问题描述】:

如何将此结构/联合从 C++ 代码转换为我的 C#-UWP 代码?重要的是,逻辑和引用不会改变,因为这个结构必须发送到服务器。

与本文的区别(Convert C++ struct to C#

  • 我的结构中有非原始数据类型(作为另一个结构和 long[])
  • 我的结构中有联合
typedef struct _HEADER
{
    _HEADER_TYPE HeaderType;
    ULONG cc;

    union
    {
        struct 
        {
            LONG Protocol;

            _TYPE CType;

            _INFO InfoDesired;  // -> that's another struct

            LONG ResolutionX[MAX_]; // -> how do i initialize an array in c# with maximum size ? 
            LONG ResolutionY[MAX_];
        } Identification;

        struct 
        {
            LONG Width;           
            _TYPE Type;
            _INFO Info; // -> that's another struct
        } Buffer;
    } u;
} _HEADER, *_HEADER;

_HEADER_TYPE 是一个枚举:

public enum _HEADER_TYPE
        {
            _HEADER_TYPE_IDENTIFICATION,
            _HEADER_TYPE_PING
        }

_INFO 是一个结构体:

public struct _INFO

    {
        public TJ S;
        public long Q;

        public long R1;   
    }

TJ 是一个枚举:

public enum TJSAMP
{
       _44,
       _42            
}

_TYPE 是一个枚举:

public enum _TYPE
{
      _OFF
      _ON
}

到目前为止我尝试过的(C# 代码):

  [StructLayout(LayoutKind.Explicit,Size=TotalBytesInStruct),Serializable]
    public struct _HEADER 
{ 
    [FieldOffset(0)]
    public _HEADER_TYPE HeaderType;
    [FieldOffset(2)]
    public ulong cc;
    [FieldOffset(4)] 
    public longProtocol;
    [FieldOffset(4)]
    public _TYPE CType;
    [FieldOffset(4)]
    public _INFO InfoDesired;  // -> that's another struct
    [FieldOffset(4)]
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 15)]
    public long[] ResolutionX; 
    [FieldOffset(4)]
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 15)]
    public long[] ResolutionY;
    [FieldOffset(8)]
    public long Width;     
    [FieldOffset(8)]      
    public _TYPE Type;
    [FieldOffset(8)]
    public _INFO Info; // -> that's another struct
 }

这和上面的 c++ 结构完全一样吗?

【问题讨论】:

标签: c# c++ struct uwp unions


【解决方案1】:

这是我得到的,假设是一个打包的布局(并非总是如此,您需要检查您的 C++ 代码):

public class Program
{
    public static void Main()
    {
        Console.WriteLine($"sizeof(_INFO): {Marshal.SizeOf(typeof(_INFO))}");
        Console.WriteLine($"sizeof(Identification): {Marshal.SizeOf(typeof(Identification))}");
        Console.WriteLine($"sizeof(Buffer): {Marshal.SizeOf(typeof(Buffer))}");
        Console.WriteLine($"sizeof(_HEADER): {Marshal.SizeOf(typeof(_HEADER))}");
        Console.WriteLine();

        Console.WriteLine("To prove that it behaves union-like:");
        var header = new _HEADER();
        header.Identification.Protocol = 5;
        Console.WriteLine($"header.Identification.Protocol: {header.Identification.Protocol}");
        Console.WriteLine($"header.Buffer.Width: {header.Buffer.Width}");
    }

    public const int MAX_ = 10;
}

public enum TJ { _44, _42 }

public enum _TYPE { _OFF, _ON }

public enum _HEADER_TYPE { _HEADER_TYPE_IDENTIFICATION, _HEADER_TYPE_PING }

[StructLayout(LayoutKind.Explicit, Pack=4, Size=20)]
public struct _INFO
{
    [FieldOffset(0)] public TJ S;
    [FieldOffset(4)] public long Q;
    [FieldOffset(12)] public long R1;   
}

[StructLayout(LayoutKind.Explicit, Pack=4, Size=32+2*8*Program.MAX_)]
public struct Identification
{
    [FieldOffset(0)] public long Protocol;
    [FieldOffset(8)] public _TYPE CType;
    [FieldOffset(12)] public _INFO InfoDesired;

    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = Program.MAX_)]
    [FieldOffset(32)] public long[] ResolutionX;

    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = Program.MAX_)]
    [FieldOffset(32 + Program.MAX_ * 8)] public long[] ResolutionY;
}

[StructLayout(LayoutKind.Explicit, Pack=4, Size=32)]
public struct Buffer
{
    [FieldOffset(0)] public long Width;
    [FieldOffset(4)] public _TYPE Type;
    [FieldOffset(12)] public _INFO Info;
}

[StructLayout(LayoutKind.Explicit, Pack=4, Size=204)]
public struct _HEADER
{
    // First slot (4 bytes)
    [FieldOffset(0)] public _HEADER_TYPE HeaderType;

    // Second slot (8 bytes)
    [FieldOffset(4)] public ulong cc;

    // The next 2 structs share the third slot (204 bytes)
    [FieldOffset(12)] public Identification Identification;
    [FieldOffset(12)] public Buffer Buffer;
}

输出:

sizeof(_INFO): 20
sizeof(Identification): 192
sizeof(Buffer): 32
sizeof(_HEADER): 204

To prove that it behaves union-like:
header.Identification.Protocol: 5
header.Buffer.Width: 5

需要注意的是:

  • enum 基本上是int,所以它使用 4 个字节;
  • long 使用 8 个字节;
  • FieldOffset的参数是字节;
  • 您需要在 C++ 代码和 C# 代码之间保持 MAX_ 同步。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多