将C++结构转换为 C# 结构

本文关键字:结构 转换 C++ | 更新日期: 2023-09-27 18:34:35

我需要将结构转换为字节,以便我可以通过网络发送或接收它。

假设结构如下所示:

struct Info
{
    unsigned int Age;
    char Name[];
};

我在 C# sharp 中有等效的结构,即:

[StructLayout(LayoutKind.Sequential)]
public struct Info
{
    public uint Age;
    public string Name;
};

要将 C# 结构转换为字节,我使用此方法:

    public Byte[] GetBytes(Info info)
    {
        int size = Marshal.SizeOf(info);
        byte[] arr = new byte[size];
        IntPtr ptr = Marshal.AllocHGlobal(size);
        Marshal.StructureToPtr(info, ptr, true);
        Marshal.Copy(ptr, arr, 0, size);
        Marshal.FreeHGlobal(ptr);
        return arr;
    }

要将接收到的字节转换为结构C++我使用此方法:

Info GetInfo(const char* bytes)
{
    Info info;
    memcpy(&info, bytes, sizeof(info));
    return info;
}

我的问题是结构的 Age 字段转换得很好,但名称字段永远不会是已发送的内容。

更新

我可以使用下面的代码轻松地将字符串转换为字节,并将其从 c# 客户端应用程序发送到 c++ 服务器应用程序。

        byte[] buffer = Encoding.UTF8.GetBytes(text + "'0");

所以我决定更改 C# 结构,如下所示:

[StructLayout(LayoutKind.Sequential)]
public struct Info
{
    public uint Age;
    public byte[] Name;
};

但在这种情况下,GetBytes(( 方法崩溃了。

将C++结构转换为 C# 结构

  1. 您的C++结构使用灵活的数组成员作为最后一个元素,这是从 C99 借来的扩展:

    从本质上讲,这意味着一个未知长度的数组结束了它。
    由于长度未知,因此当询问结构大小时,编译器将假定0
    我不知何故怀疑这就是你想要的。

  2. C# 结构具有 string 成员,它不是值类型。

    只是像您一样将托管指针复制到它是非常荒谬的。

那么,你应该怎么做呢?

定义您自己的连线格式。

  • unsigned 32 位整数将很容易封送。
  • 字符串更难。您是否有一个哨兵值,而不是字符串的一部分?
    或者您是否必须使用/更喜欢计数字符串,在这种情况下,您必须决定大小的类型并首先封送?

    另外,不要忘记字符集:更喜欢 UTF-8,但如果它只是窗口,UTF-16 小端序也可能是一个可行的选择。

这很快就会变得非常复杂。

你可能想看看一些可以提供帮助的库 - Google Protobuf和Apache Thrift立即浮现在脑海中。两者都支持C++和 C# 以及其他语言。