将C++结构转换为 C# 结构
本文关键字:结构 转换 C++ | 更新日期: 2023-09-27 18:34:35
我需要将结构转换为字节,以便我可以通过网络发送或接收它。
假设结构如下所示:
struct Info
{
unsigned int Age;
char Name[];
};
我在 C# sharp 中有等效的结构,即:
[StructLayout(LayoutKind.Sequential)]
public struct Info
{
public uint Age;
public string Name;
};
要将 C# 结构转换为字节,我使用此方法:
public Byte[] GetBytes(Info info)
{
int size = Marshal.SizeOf(info);
byte[] arr = new byte[size];
IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(info, ptr, true);
Marshal.Copy(ptr, arr, 0, size);
Marshal.FreeHGlobal(ptr);
return arr;
}
要将接收到的字节转换为结构C++我使用此方法:
Info GetInfo(const char* bytes)
{
Info info;
memcpy(&info, bytes, sizeof(info));
return info;
}
我的问题是结构的 Age 字段转换得很好,但名称字段永远不会是已发送的内容。
更新
我可以使用下面的代码轻松地将字符串转换为字节,并将其从 c# 客户端应用程序发送到 c++ 服务器应用程序。
byte[] buffer = Encoding.UTF8.GetBytes(text + "'0");
所以我决定更改 C# 结构,如下所示:
[StructLayout(LayoutKind.Sequential)]
public struct Info
{
public uint Age;
public byte[] Name;
};
但在这种情况下,GetBytes(( 方法崩溃了。
-
您的C++结构使用灵活的数组成员作为最后一个元素,这是从 C99 借来的扩展:
从本质上讲,这意味着一个未知长度的数组结束了它。
由于长度未知,因此当询问结构大小时,编译器将假定0
。
我不知何故怀疑这就是你想要的。 -
C# 结构具有
string
成员,它不是值类型。只是像您一样将托管指针复制到它是非常荒谬的。
那么,你应该怎么做呢?
定义您自己的连线格式。
unsigned
32 位整数将很容易封送。-
字符串更难。您是否有一个哨兵值,而不是字符串的一部分?
或者您是否必须使用/更喜欢计数字符串,在这种情况下,您必须决定大小的类型并首先封送?另外,不要忘记字符集:更喜欢 UTF-8,但如果它只是窗口,UTF-16 小端序也可能是一个可行的选择。
这很快就会变得非常复杂。
你可能想看看一些可以提供帮助的库 - Google Protobuf和Apache Thrift立即浮现在脑海中。两者都支持C++和 C# 以及其他语言。