我需要将结构转换为字节,以便我可以通过网络发送或接收它。
假设结构如下所示:
struct Info
{
unsigned int Age;
char Name[];
};
我在C#sharp中有相同的结构,它是:
[StructLayout(LayoutKind.Sequential)]
public struct Info
{
public uint Age;
public string Name;
};
要将C#struct转换为byte,请使用以下方法:
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#client app发送到c ++ server app。
byte[] buffer = Encoding.UTF8.GetBytes(text + "\0");
所以我决定改变C#结构如下:
[StructLayout(LayoutKind.Sequential)]
public struct Info
{
public uint Age;
public byte[] Name;
};
但在这种情况下,GetBytes()方法崩溃。
答案 0 :(得分:4)
您的C ++ - 结构使用灵活的数组成员作为最后一个元素,这是从C99借用的扩展:
本质上,它意味着一个未知长度的数组结束它
由于长度未知,编译器在询问结构大小时会假设 0
。
我莫名其妙地怀疑你想要的是什么。
您的C#-structure有一个string
- 成员,它不是值类型。
只需像你那样将托管指针复制到它就非常荒谬。
那么,你应该怎么做?
unsigned
32位整数很容易编组。字符串更难。你有一个哨兵值永远不会成为弦乐的一部分吗? 或者您是否必须使用/更喜欢计算字符串,在这种情况下,您必须决定大小的类型并首先编组?
另外,不要忘记字符集:首选UTF-8,但如果它只是windows,UTF-16 little-endian也可能是一个可行的选择。
< / LI>答案 1 :(得分:1)
这很快就会非常复杂。
您可能希望查看一些可以提供帮助的库 - Google Protobuf和Apache Thrift立即浮现在脑海中。两者都支持C ++和C#等语言。