为了更好地理解这个话题,我会先总结一下我最初的问题,然后再讨论这个话题的实际问题。如果你不想阅读,忽略总结部分,直接进入第二节,当我实际解释问题时。
总结了问题
我正在模拟一个已经存在的游戏的MMORPG服务器(只是为了学习,我已经知道发布它在任何方面都是非法的),当我将原始数据包缓冲区“转换”到代码中的某种结构时,我将面临很多麻烦,我可以使用这些结构来避免通过缓冲区中的偏移来引用数据包中的数据。
我对倒车和C++有一些背景。这个问题在C++中很容易通过以下操作解决(考虑'packetBuffer‘作为一个'char*')。
MyStructureType* packet = (MyStructureType*)&packetBuffer[0];问题的根源在于C#提供的用户内存管理的自由度要小得多。我仍然可以用指针,但有很多事情我不能做。考虑一下用来表示包Y的struct,如果X需要声明另一个结构的固定大小的数组,即使所涉及的所有类型都是闪电式,我就有麻烦了: C#只是不允许这样做)。因此,我采取的解决方案是将这些数据包结构作为类,格式化它们的布局(使用属性作为StructLayout和MarshalAs),然后使用Marshal.PtrToStructure和Marshal.StructureToPtr方法来转换一些高级表示形式的原始缓冲区(byte[]),反之亦然。现在我们来谈谈我的实际问题。
实际问题
好的,如上所述,我有POD类,用作数据包数据的高级表示(byte[])。假设数据包表示一个复杂的结构,其中包含一些嵌套的自定义结构。直到我必须声明一个固定大小的数组(由“可封送处理”类表示)为止,这一切都很好。假设我在Y类中声明了一个包含类X的3个元素的数组,最后将有3个引用(指针)来引用X的实际数据,而不是Y的缓冲区中的3个元素“硬编码”。
[StructLayout(LayoutKind.Sequential)]
class X
{
int i1;
int i2;
}
[StructLayout(LayoutKind.Sequential)]
class Y
{
X _x1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
X[] _x2;
}实例化Y时,我将得到一个对象,它有20个字节,而不是32个( _x1为8个字节,三个元素of_x2的每个数据为3个指针,每个指针为12个字节)。
因此,最后一个问题是:如何使_x2在Y中硬编码而不是存储指针?
谢谢。
https://stackoverflow.com/questions/36610615
复制相似问题