可以使用BitConverter从IL字节流中可靠地提取多字节值(由MethodBody.GetILAsByteArray返回)吗?

时间:2012-08-12 11:30:35

标签: clr endianness cil system.reflection bitconverter

我正在研究一些解析由MethodBody.GetILAsByteArray返回的IL字节数组的代码。

假设我想从这样的IL字节流中读取元数据标记或32位整数常量。起初我以为使用BitConverter.ToInt32(byteArray, offset)会让这很容易。但是我现在担心这对大端机器不起作用。

据我所知,IL总是对多字节值使用little-endian编码:

  

“所有参数编号都是编码最小有效字节的最小字节地址(通常称为'little-endian'的模式)。” - The Common Language Infrastructure Annotated Standard,分区III, CH。 1.2(第482页)。

由于BitConverter的转换方法符合计算机体系结构的字节序(可通过BitConverter.IsLittleEndian发现),因此我得出结论:BitConverter不应用于从中提取多字节值一个IL字节流,因为这会在big-endian机器上产生错误的结果。

这个结论是否正确?

  • 如果是:有没有办法告诉BitConverter哪个字节序用于转换,或者BCL中是否有其他提供此功能的类,或者我是否必须编写自己的转换码?

  • 如果不是:我哪里错了?什么是提取的正确方法,例如来自IL字节数组的Int32操作数值?

1 个答案:

答案 0 :(得分:1)

在传递它之前,你应该总是在一个小的endian数组上执行此操作:

// Array is little. Are we on big?
if (!BitConverter.IsLittleEndian)
{
    // Then flip it
    Array.Reverse(array);
}
int val = BitConverter.ToInt32(...);

但是,当你提到IL流时。字节码是这个(AFAIK):

(OPCODE:(1|2):little) (VARIABLES:x:little)

所以我会读取一个字节,检查其操作码,然后读取相应的字节,并在必要时使用上面的代码翻转数组。我可以问你在做什么吗?