C++ struct/union 到 C# 结构
C++ struct/union into C# struct
如何将此 struct/union 从 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++ 代码):
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个字节;
- a
long
使用 8 个字节;
FieldOffset
的参数以字节为单位;
- 您需要
MAX_
在 C++ 代码和 C# 代码之间保持同步。
如何将此 struct/union 从 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++ 代码):
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个字节; - a
long
使用 8 个字节; FieldOffset
的参数以字节为单位;- 您需要
MAX_
在 C++ 代码和 C# 代码之间保持同步。