【发布时间】:2015-02-16 12:52:18
【问题描述】:
我需要将结构转换为字节,以便我可以通过网络发送或接收它。
假设结构如下所示:
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 字段转换得很好,但 Name 字段从来不是已发送的内容。
更新
我可以使用下面的代码轻松地将字符串转换为字节,并将其从 c# 客户端应用程序发送到 c++ 服务器应用程序。
byte[] buffer = Encoding.UTF8.GetBytes(text + "\0");
所以我决定将 C# 结构更改如下:
[StructLayout(LayoutKind.Sequential)]
public struct Info
{
public uint Age;
public byte[] Name;
};
但在这种情况下,GetBytes() 方法会崩溃。
【问题讨论】:
-
您能否提供一些信息,说明您为什么需要一个结构,以及为什么需要将其转换为字节?
-
有点难;你能看到“在线”传输的内容吗?
-
如果年龄有效但名称无效,您可能正在处理某种字符集编码不匹配问题。
-
C++ 代码没有使用
CMsg。我糊涂了。在任何情况下,我相信 C++ 中结构的大小是由实现定义的(特别是因为您使用的是“C struct hack”)。名称的长度可变。在 C# 中,string成员只是对在堆上分配的实际字符串的引用,因此除了复制结构的字节之外,您还需要做更多的工作。 -
转换整个结构永远不会正确。您必须逐场进行。在 c# 方面,您最有可能获得字符串大小和字符串内容,而在 C++ 方面,没有长度。另外,在 C# 端字符串是 Unicode,每个字符 16 位,而在 C++ 端它们只是字符。我建议使用像kentonv.github.io/capnproto 这样的罐装解决方案