【发布时间】:2010-03-18 16:30:31
【问题描述】:
假设我有一个字节集合
var bytes = new byte[] {0, 1, 2, 3, 4, 5, 6, 7};
我想从字节中提取一个定义的值作为托管类型,例如ushort。有什么简单的方法可以定义哪些类型驻留在集合中的哪个位置并提取这些值?
一种(丑陋的)方法是使用带有索引的System.BitConverter 和Queue 或byte[] 并简单地遍历,例如:
int index = 0;
ushort first = System.BitConverter.ToUint16(bytes, index);
index += 2; // size of a ushort
int second = System.BitConverter.ToInt32(bytes, index);
index += 4;
...
当您处理大量此类结构时,此方法会变得非常非常乏味!
我知道System.Runtime.InteropServices.StructLayoutAttribute 允许我在结构或类中定义类型的位置,但似乎没有办法将字节集合导入该结构。如果我能以某种方式将结构覆盖在字节集合上并提取值,那将是理想的。例如
Foo foo = (Foo)bytes; // doesn't work because I'd need to implement the implicit operator
ushort first = foo.first;
int second = foo.second;
...
[StructLayout(LayoutKind.Explicit, Size=FOO_SIZE)]
public struct Foo {
[FieldOffset(0)] public ushort first;
[FieldOffset(2)] public int second;
}
关于如何实现这一点的任何想法?
[编辑:另见我的question on how to deal with the bytes when they are big endian。]
【问题讨论】:
-
您感兴趣的所有类型都是积分(或“固定”积分数组)吗?
-
@gooch:不,但我们可以解决这个问题,并在我们有字符串时编写辅助方法。
-
好的,这对于整数类型非常有效。对于这些类型的数组来说有点麻烦,因为它们需要被指定为“固定的”(这实际上意味着它是一个指向内存开头的指针)。我们无法实现其他类型,但是有一种方法可以为每个字段指定 Size,这很快就会变得很麻烦。
标签: .net interop binary legacy