1

我正在编写一个特殊用途的迷你编译器,我经常查看反汇编的 CIL 来弄清楚如何做事。但如何将反汇编代码转换为 Reflection.Emit 调用通常并不明显。是否存在参考手册或任何其他信息来源来进行此翻译?

编辑:是的,将操作码映射到 ILGenerator 非常简单;我说的是所有其他的东西,比如 .directives 和属性。例如,您如何知道如何编写 Reflection.Emit 等价物Dictionary<TKey,TValue>

.class public auto ansi serializable beforefieldinit Dictionary<TKey, TValue>
    extends System.Object
    implements System.Collections.Generic.IDictionary`2<!TKey, !TValue>,
    System.Collections.Generic.ICollection`1<valuetype 
        System.Collections.Generic.KeyValuePair`2<!TKey, !TValue>>, 
    ...
{
    .custom instance void System.Diagnostics.DebuggerDisplayAttribute::
        .ctor(string) = { string('Count = {Count}') }

    .method public hidebysig newslot virtual final instance bool TryGetValue
        (!TKey key, [out] !TValue& 'value') cil managed
    {
        .maxstack 3
        .locals init ([0] int32 num)
        ...

或者“参数”指令怎么样?

// public static void SayHello(string s = "Hello World!")
.method public hidebysig static void SayHello([opt] string s) cil managed
{
    .param [1] = "Hello World!"
4

3 回答 3

4

为此,我将使用BLToolkit的EmitHelper 组件。它提供了一个类似于 IL 代码的流畅 API,封装了 Reflection.Emit。从链接文章中提取的示例:

EmitHelper emit = new AssemblyBuilderHelper("HelloWorld.dll")
    .DefineType  ("Hello", typeof(object), typeof(IHello))
    .DefineMethod(typeof(IHello).GetMethod("SayHello"))
    .Emitter;
emit
    // string.Format("Hello, {0}!", toWhom)
    //
    .ldstr   ("Hello, {0}!")
    .ldarg_1
    .call    (typeof(string), "Format", typeof(string), typeof(object))

    // Console.WriteLine("Hello, World!");
    //
    .call    (typeof(Console), "WriteLine", typeof(string))
    .ret();

Type type = emit.Method.Type.Create();
于 2010-06-16T06:40:24.253 回答
1

您正在查看 System.Collections.Generic.Dictionary<> 类的 IL。“字典”类名是您传递给 ModuleBuilder.DefineType() 的字符串。

.param 属性是在 C# 版本 4 或 VB.NET 中为具有默认值的参数生成的。您使用从 MethodBuilder.DefineParameter() 返回的 ParameterBuilder 设置它。使用 SetConstant() 方法。

于 2010-06-13T21:03:28.980 回答
1

由于没有人能回答这个问题,我得出的结论是不存在任何文档来显示 ilasm 语法和 Reflection.Emit 调用之间的关系。

附带说明一下,我发现在运行时使用RunSharp创建代码通常比 Reflection.Emit 更好。当我有时间时,我会尝试找出新版本的Cecil

于 2011-04-10T21:15:52.263 回答