【问题标题】:Field-wise comparison of unmanaged struct非托管结构的字段比较
【发布时间】:2011-04-19 04:42:31
【问题描述】:

出于测试目的,我想比较从非托管代码封送的两个结构(未知类型 T)。

因为它们可能包含一些非托管表示的包装,所以将整个结构转换为字节数组然后逐字节比较是不合适的:

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;

有没有办法做到这一点? 或者有没有更好的方法来比较非托管结构?

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

【问题讨论】:

    标签: c# struct marshalling alignment


    【解决方案1】:

    你能用Marshal.SizeOf(fieldInfo.FieldType)吗?

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多