如何编组包含可变大小字符串的结构?

时间:2014-02-26 16:29:46

标签: c# tcp struct marshalling unmarshalling

我正在通过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; }
}

我通常通过在Size属性中指定StructLayout来使这些结构生效。但是,现在我有两个不同大小的字符串,我不能为我的生活找出如何让Marshal获取一个数据包(这是一个字节数组)并让它编组它回到上面的结构,因为我不能将它指定为LPStr并设置它的大小 - 它会有所不同。

所以每当我尝试这个时,元帅都会对我大喊大叫,说:

Type 'HotspotUpdate' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed.

有什么方法可以让我的工作,或者我不得不求助于只发送一个字节数组的字符串并在服务器端解决它?

1 个答案:

答案 0 :(得分:1)

CLR要求结构成员位于固定的偏移量。因此,没有可变大小的成员。

或许,您应该使用更高级别的抽象。使用协议缓冲区以方便,可靠的方式自动化所有序列化需求。