我再次通过 UDP 从 C++ 程序接收结构, 现在我将结构移植到 C#,示例:
[Serializable]
struct sample
{
public int in;
public byte[] arr;
public int[] arr2;
public float fl;
}
好的,反序列化器如何知道一个数组何时结束而另一个数组开始? 能以某种方式指定数组有多大吗? 我不想使用 fixed,因为这会使我的代码不安全,而且我也不能使用构造函数,因为不允许结构包含不带参数的构造函数。
有什么建议吗?
//编辑:
已知数组的长度为 32 和 4。 问题是我不知道如何将此信息传递给解串器
然后发件人是 C++ 的作品是这样的:
char* pr = &sample;
int i=0;
while (i<sizeof(sample))
{
udp.send(*(pr+i))
i++;
}
最佳答案
既然你已经告诉我们长度是预定义的长度,那么下面的陈述就变得更清楚了:
I don't know how to pass this information to the deserialiser
事实上,它变得没有实际意义。这里没有预定义的序列化程序可以帮助您。您有两个选择:
A:编写您自己的序列化程序,并在您知道格式后处理数据 - 可能使用 BinaryReader
:
using(var reader = new BinaryReader(source)) {
int in = reader.ReadInt32();
byte[] arr = reader.ReadBytes(32);
int[] arr2 = new int[4];
for(int i = 0 ; i < 4 ; i++) arr2[i] = reader.ReadInt32();
float fl = reader.ReadSingle();
var obj = /* something involving ^^^ */
}
B:缓冲区 56 字节,并使用非常讨厌的 unsafe
/fixed
/pointer-banging code
我强烈建议第一个。特别是,这还允许您在需要时解决字节序问题。
以对您来说神圣的一切为名,请勿这样做:
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Explicit)]
unsafe struct sample
{
[FieldOffset(0)] public int @in;
[FieldOffset(4)] public fixed byte arr[32];
[FieldOffset(36)] public fixed int arr2[4];
[FieldOffset(52)] public float fl;
}
static class Program
{
unsafe static void Main()
{
byte[] buffer = new byte[56];
new Random().NextBytes(buffer); // some data...
sample result;
fixed(byte* tmp = buffer)
{
sample* ptr = (sample*) tmp;
result = ptr[0];
}
Console.WriteLine(result.@in);
Console.WriteLine(result.fl);
}
}
对于较大的缓冲区,您可以将ptr
视为多个sample
的不安全数组,通过索引访问:
int @in = ptr[i].@in;
(等)
但老实说......有很多“邪恶”的东西,老实说我不知道从哪里开始......只是......除非你绝对知道每一行有做,以前做过,并且了解所有的陷阱......甚至不要去想它
关于c# - 反序列化结构数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11203202/