C++ 结构体/联合体到 C# 结构体 [英] C++ struct/union into C# struct
本文介绍了C++ 结构体/联合体到 C# 结构体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
如何将此结构/联合从 C++ 代码转换为我的 C#-UWP 代码?重要的是,逻辑和引用不会改变,因为这个结构必须发送到服务器.
How do I convert this struct/union from C++ code into my C#-UWP-code? The important thing is, that the logic and references does not change because this struct must be sent to a server.
与本文的不同之处(将 C++ struct 转换为 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 是一个枚举:
_HEADER_TYPE is an enum:
public enum _HEADER_TYPE
{
_HEADER_TYPE_IDENTIFICATION,
_HEADER_TYPE_PING
}
_INFO 是一个结构体:
_INFO is a struct:
public struct _INFO
{
public TJ S;
public long Q;
public long R1;
}
TJ 是一个枚举:
public enum TJSAMP
{
_44,
_42
}
_TYPE 是一个枚举:
_TYPE is an enum:
public enum _TYPE
{
_OFF
_ON
}
到目前为止我尝试过的(C# 代码):
What I've tried so far (C# code):
[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++结构完全一样吗?
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):
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# 代码之间保持同步.
- an
enum
is basically anint
, so it uses 4 bytes; - a
long
uses 8 bytes; - the argument of
FieldOffset
is in byte; - you need to keep
MAX_
in sync between C++ code and C# code.
这篇关于C++ 结构体/联合体到 C# 结构体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文