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

时间:2014-12-17 20:51:33

标签: c# c++ struct converter

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

假设结构如下所示:

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

我在C#sharp中有相同的结构,它是:

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

要将C#struct转换为byte,请使用以下方法:

    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字段转换得很好,但Name字段永远不会被发送。

更新

我可以使用下面的代码轻松地将字符串转换为字节,并将其从c#client app发送到c ++ server app。

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

所以我决定改变C#结构如下:

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

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

2 个答案:

答案 0 :(得分:4)

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

    本质上,它意味着一个未知长度的数组结束它 由于长度未知,编译器在询问结构大小时会假设 0
    我莫名其妙地怀疑你想要的是什么。

  2. 您的C#-structure有一个string - 成员,它不是值类型。

    只需像你那样将托管指针复制到它就非常荒谬。

  3. 那么,你应该怎么做?

    定义您自己的有线格式。

    • unsigned 32位整数很容易编组。
    • 字符串更难。你有一个哨兵值永远不会成为弦乐的一部分吗? 或者您是否必须使用/更喜欢计算字符串,在这种情况下,您必须决定大小的类型并首先编组?

      另外,不要忘记字符集:首选UTF-8,但如果它只是windows,UTF-16 little-endian也可能是一个可行的选择。

      < / LI>

答案 1 :(得分:1)

这很快就会非常复杂。

您可能希望查看一些可以提供帮助的库 - Google ProtobufApache Thrift立即浮现在脑海中。两者都支持C ++和C#等语言。