我正在研究一些解析由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
操作数值?
答案 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)
所以我会读取一个字节,检查其操作码,然后读取相应的字节,并在必要时使用上面的代码翻转数组。我可以问你在做什么吗?