我想使用套接字将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 ++结构吗?
由于
答案 0 :(得分:5)
marshaller可以帮助您在.NET结构和原始字节之间进行转换。在this answer中,我发布了一个简单的解决方案,归结为Marshal.StructureToPtr
和Marshal.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