出于测试目的,我想比较两个从非托管代码编组的结构(未知类型为T)。
因为它们可能包含非托管表示中的某些打包,所以将整个struct转换为字节数组然后逐字节进行比较是不合适的:
int size = Marshal.SizeOf(typeof(T));
IntPtr buf1 = Marshal.AllocHGlobal(size); // FreeHGlobal omitted for simplicity
IntPtr buf2 = Marshal.AllocHGlobal(size);
byte[] array1 = new byte[size];
byte[] array2 = new byte[size];
Marshal.StructureToPtr(st1, buf1, false);
Marshal.StructureToPtr(st2, buf2, false);
Marshal.Copy(buf1, array1, 0, size);
Marshal.Copy(buf2, array2, 0, size);
// inapropriate
for (int i = 0; i < size; ++i)
{
if (array1[i] != array2[i]) { return false; }
}
return true;
我认为有必要逐场比较。
感谢反射,我可以枚举FieldInfo,然后使用Marshal.OffsetOf方法我可以获得字段的偏移量。
不幸的是,我不知道如何获得字段的大小。 没有它,我想我无法比较两个消除包装效果的领域。
foreach (var fieldInfo in typeof(T).GetFields())
{
int offset = (int)Marshal.OffsetOf(typeof(T), fieldInfo.Name);
int fieldSize = ...; // I need this
for (int i = offset; i < offset + fieldSize; ++i)
{
if (array1[i] != array2[i]) { return false; }
}
}
return true;
有没有办法实现这个目标? 或者是否有更好的方法来比较非托管结构?
注意: 字段类型是任意的(可以是原始整数,数组,字符串,枚举,结构等)。
答案 0 :(得分:0)
您可以使用Marshal.SizeOf(fieldInfo.FieldType)
吗?
另外,这两种结构可能有不同的包装吗?因为如果他们不是,包装不会变得无关紧要吗?你能给出一个例子,说明打包意味着直接的逐字节比较会给你错误的答案吗?我假设当分配内存时,它被清零 - 因此任何未使用的字节(由于填充)将为零,因此在两个数组中都相等。