我正在通过TCP连接从客户端向我的服务器发送数据包( MemoryStream
),在服务器端我想通过使用Marshal重新创建原始对象 . 我正在使用以下代码将内容编组到数据包中:
public void Write<T>(T value) where T : struct
{
byte[] buffer = new byte[Marshal.SizeOf(typeof(T))];
// Fill the buffer with our stuff please!
fixed (byte* b = buffer)
Marshal.StructureToPtr(value, new IntPtr(b), false);
// And write it to the MemoryStream. Kthx!
Write(buffer, 0, buffer.Length);
}
当我把数据写入数据包时,我在其上调用 ToArray()
并将其发送到服务器 . 然后,服务器将接收包含其中所有数据的字节数组 .
这适用于所有原始类型,但它对我的自定义结构不太好用 . 考虑我正在使用的以下结构:
[StructLayout(LayoutKind.Sequential)]
public struct HotspotUpdate
{
public string LeaderHash { get; set; }
public string OurName { get; set; }
public CommandSide Side { get; set; }
public CommandType Type { get; set; }
public Vector3 Location { get; set; }
}
我通常通过在 StructLayout
属性中指定 Size
来使这些结构工作 . 但是,现在我有两个不同大小的字符串,我不能为我的生活弄清楚如何让 Marshal
获取一个数据包(这是一个字节数组)并让它将它编组回到以上结构,因为我不能将其指定为 LPStr
并设置其大小 - 它会有所不同 .
因此,每当我尝试这样做时,元帅会对我大喊大叫,说:
Type 'HotspotUpdate' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed.
有什么办法可以让我的工作,或者我不得不求助于只发送一个字节数组的字符串并在服务器端解决它?
1 回答
CLR要求结构成员位于固定的偏移量 . 因此,没有可变大小的成员 .
或许,你应该使用更高级别的抽象 . 使用协议缓冲区以方便,可靠的方式自动化所有序列化需求 .