非托管结构的字段比较

时间:2010-09-30 06:07:42

标签: c# struct marshalling alignment

出于测试目的,我想比较两个从非托管代码编组的结构(未知类型为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;

有没有办法实现这个目标? 或者是否有更好的方法来比较非托管结构?

注意: 字段类型是任意的(可以是原始整数,数组,字符串,枚举,结构等)。

1 个答案:

答案 0 :(得分:0)

您可以使用Marshal.SizeOf(fieldInfo.FieldType)吗?

另外,这两种结构可能有不同的包装吗?因为如果他们不是,包装不会变得无关紧要吗?你能给出一个例子,说明打包意味着直接的逐字节比较会给你错误的答案吗?我假设当分配内存时,它被清零 - 因此任何未使用的字节(由于填充)将为零,因此在两个数组中都相等。