[英]C++ struct/union into C# struct
How do I convert this struct/union from C++ code into my C#-UWP-code? 如何将这种struct / union从C ++代码转换为我的C#-UWP代码? The important thing is, that the logic and references does not change because this struct must be sent to a server.
重要的是,逻辑和引用不会更改,因为必须将此结构发送到服务器。
the difference to this article ( Convert C++ struct to C# ) 与本文的区别( 将C ++结构转换为C# )
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 is an enum: _HEADER_TYPE是一个枚举:
public enum _HEADER_TYPE
{
_HEADER_TYPE_IDENTIFICATION,
_HEADER_TYPE_PING
}
_INFO is a struct: _INFO是一个结构:
public struct _INFO
{
public TJ S;
public long Q;
public long R1;
}
TJ is an enum: TJ是一个枚举:
public enum TJSAMP
{
_44,
_42
}
_TYPE is an enum: _TYPE是一个枚举:
public enum _TYPE
{
_OFF
_ON
}
What I've tried so far (C# code): 到目前为止,我已经尝试过(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
}
Does this exactly the same as the c++ struct above ? 这和上面的c ++结构完全一样吗?
Here is what I got, assuming a packed layout (which is not always the case, you will need to check your C++ code): 这是我得到的,假设布局紧凑(情况并非总是如此,您将需要检查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;
}
Output: 输出:
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
The points to note are that: 需要注意的几点是:
enum
is basically an int
, so it uses 4 bytes; enum
基本上是一个int
,所以它使用4个字节; long
uses 8 bytes; long
使用8个字节; FieldOffset
is in byte; FieldOffset
的参数以字节为单位; MAX_
in sync between C++ code and C# code. MAX_
在C ++代码和C#代码之间保持同步。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.