通过套接字将C#结构发送到C ++

时间:2011-04-08 12:02:14

标签: c# c++ sockets struct byte

我想使用套接字将C#中的结构发送到C ++。

例如,我使用这个结构:

[StructLayout(LayoutKind.sequential, Pack = 1)]
struct pos {
    public int i;
    public float x;
};

如果我以某种方式将其转换为字节并通过网络发送,我应该能够在c ++中将其转换为此内容:

struct pos {
    int i;
    float x;
};

......我想。

1)如何在C#中分解结构实例以通过网络发送它?

2)一旦得到它,我可以安全地将其转换为c ++结构吗?

由于

2 个答案:

答案 0 :(得分:5)

marshaller可以帮助您在.NET结构和原始字节之间进行转换。在this answer中,我发布了一个简单的解决方案,归结为Marshal.StructureToPtrMarshal.PtrToStructure。与Johann du Toit提供的更高级的解决方案相比,在我看来,如果您想要做的就是通过字节流推送一些结构,那么您可以做的最好的事情。

如果执行此操作,如果长度正确,则可以安全地转换为C ++结构,并且使用与C#结构相同的包装声明C ++结构(即VC ++中的#pragma pack__attribute__((packed))在GCC)。

请注意,这也适用于固定长度的C字符串,但不会处理较大值的字节序。我发现这是一个简单的解决方案,可以为后一个问题提供getter和setter,只需相应地交换字节(使用BitConverter)。


对包装的一些阐述: 采用以下结构:

struct MyStruct {
    uint8_t a;
    float b;
};

使用带有StructLayout的C#声明,Pack = 1,此结构的大小为五个字节。但是,C ++结构可能有八个字节(甚至更多),具体取决于编译器的默认打包,他们可能会愉快地插入一些填充字节以将浮点值与32位边界对齐(仅作为示例)。因此,您必须将相同的打包应用于C#和C ++结构。在Visual C ++中:

#pragma pack(push, 1)
// ... struct declarations...
#pragma pack(pop)

这意味着在两个pragma之间声明的所有结构都将包含一个。在海湾合作委员会:

struct x {
// ...
} __attribute__((packed));

这也是一样的。您可以在Windows平台上#define __attribute__(x)和在pragma周围#ifdef _WIN32使代码与这两个世界兼容。

答案 1 :(得分:1)

您可以使用JSON之类的格式对其进行编码(有很多JSON解析器,请查看json.org网站上的列表),XML或者只是滚动自己的。您还可以尝试已经构建的库Protobuf,它允许您序列化您将使用.proto格式的文件创建的结构(并使用Protobuf-Net作为C#)。另一种选择是Thrift,它提供了一种序列化的方法,但也提供了一个随时可用的RCP系统。它默认支持c#,c ++和大量其他语言。

所以这取决于品味,请选择:D