[英]Convert C++ struct to C# struct
I need to convert a struct to bytes so that I can send or receive it over a network. 我需要将一个结构转换为字节,以便可以通过网络发送或接收它。
Let's say the struct is something like below: 假设该结构如下所示:
struct Info
{
unsigned int Age;
char Name[];
};
I have the equivalent struct in C# sharp which is: 我在C#Sharp中有等效的结构,它是:
[StructLayout(LayoutKind.Sequential)]
public struct Info
{
public uint Age;
public string Name;
};
To convert the C# struct to byte I use the this method: 要将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;
}
And to Convert the received bytes to C++ struct I use this method: 要将接收到的字节转换为C ++结构,请使用以下方法:
Info GetInfo(const char* bytes)
{
Info info;
memcpy(&info, bytes, sizeof(info));
return info;
}
My problem is that the Age field of the struct converts very well but the Name field never is what has been sent. 我的问题是该结构的Age字段转换得很好,但是Name字段从未发送过。
Update 更新资料
I can easily convert a string to bytes using the code below and send it from c# client app to c++ server app. 我可以使用下面的代码轻松地将字符串转换为字节,并将其从c#客户端应用程序发送到c ++服务器应用程序。
byte[] buffer = Encoding.UTF8.GetBytes(text + "\0");
so I decided to change the C# struct as below: 所以我决定如下更改C#结构:
[StructLayout(LayoutKind.Sequential)]
public struct Info
{
public uint Age;
public byte[] Name;
};
but in this case the GetBytes() method crashes. 但是在这种情况下,GetBytes()方法会崩溃。
Your C++-structure uses a flexible array member as the last element, which is an extension borrowed from C99: 您的C ++结构使用一个灵活的数组成员作为最后一个元素,它是从C99借来的扩展:
In essence, it means that an array of unknown length ends it. 本质上,这意味着长度未知的数组将其终止。
Because the length is not known, the compiler will, when asked for the structures size, assume 0
. 由于长度未知,因此在要求结构大小时,编译器将假定
0
。
I somehow doubt that's what you wanted. 我以某种方式怀疑那是您想要的。
Your C#-structure has a string
-member, which is not a value-type. 您的C#结构具有
string
-member,它不是值类型。
Just copying the managed pointer to it like you do is quite nonsensical. 像您一样将托管指针复制到它完全是荒谬的。
So, what should you do? 那你该怎么办?
unsigned
32-bit integer will be easily marshalled. unsigned
32位整数将很容易编组。 The string is more difficult. 字符串比较困难。 Do you have a sentinel-value never part of the string?
您是否有一个永远不属于字符串的哨兵值?
Or do you have to use / prefer counted strings, in which case you have to decide what type the size will be and marshal that first? 还是您必须使用/首选计数字符串,在这种情况下,您必须确定大小为哪种类型并首先将其编组?
Also, don't forget the character-set: Prefer UTF-8, though if it's windows-only, UTF-16 little-endian may also be a viable choice. 另外,请不要忘记字符集:最好使用UTF-8,尽管如果它仅用于Windows,则UTF-16 little-endian也是一个可行的选择。
This can get very complicated very quickly. 这很快就会变得非常复杂。
You might want to look at some libraries that can help - Google Protobuf and Apache Thrift immediately spring to mind. 您可能想看看一些可以提供帮助的库-立即想到Google Protobuf和Apache Thrift 。 Both support C++ and C# amongst other languages.
两者都支持C ++和C#等语言。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.