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

Kai*_*aan 1 c# c++ sockets byte struct

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

例如,我使用这个结构:

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

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

struct pos {
    int i;
    float x;
};
Run Code Online (Sandbox Code Playgroud)

... 我认为.

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

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

谢谢

Ore*_*ost 5

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

如果这样做,如果长度正确,您可以安全地转换为C++结构,并且使用与C#结构相同的包装声明C++结构(即#pragma pack在VC++或__attribute__((packed))GCC中).

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


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

struct MyStruct {
    uint8_t a;
    float b;
};
Run Code Online (Sandbox Code Playgroud)

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

#pragma pack(push, 1)
// ... struct declarations...
#pragma pack(pop)
Run Code Online (Sandbox Code Playgroud)

这意味着在两个pragma之间声明的所有结构都将包含一个.在GCC:

struct x {
// ...
} __attribute__((packed));
Run Code Online (Sandbox Code Playgroud)

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