使用方法Mono.Cecil能做到进口 [英] Method import using Mono.Cecil

查看:675
本文介绍了使用方法Mono.Cecil能做到进口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

帮我进口的方法讨好。
我想编织组装和从其他装配定义的基类注射方法调用引用(实际上它是在那里编织码定义的程序集)。

 私人无效InsertCallSetReference()
{
//获取加载指令来代替
VAR ilProcessor ​​= Property.SetMethod.Body.GetILProcessor();
VAR argumentLoadInstructions = ilProcessor.Body.Instructions.ToList();

MethodReference methodReference = ImportMethod(SetReference);

的foreach(在argumentLoadInstructions VAR指令)
{
如果(instruction.OpCode == OpCodes.Stfld)
{
ilProcessor.InsertAfter(指令, ilProcessor.Create(OpCodes.Call,methodReference));
ilProcessor.InsertAfter(指令,ilProcessor.Create(OpCodes.Ldarg_1));
ilProcessor.InsertAfter(指令,ilProcessor.Create(OpCodes.Ldstr,DBFieldName));
ilProcessor.InsertAfter(指令,ilProcessor.Create(OpCodes.Ldarg_0));
ilProcessor.Remove(指令);
中断;
}
}
}



方法导入代码工作得很好并返回方法参照

 私人MethodReference ImportMethod(字符串名称)
{
变种类型= MongoConnectModule.Import (typeof运算(BaseDataObject));
返回MongoConnectModule.Import(type.Resolve()方法。首先(M = GT; m.Name ==名));
}



但经过AssemblyDefinition写调用它引发我一个错误:




C:\dev\MongoConnect\WeavingTaskTest\Weaving\CodeWeaving.targets(32,5):
错误MSB4018:系统.ArgumentException:成员'System.Void
MongoConnect.BaseDataObject ::的SetProperty(System.String,System.Object的)'
的另一模块声明并需要导入




  _assemblyDefinition.Write(_assemblyPath,新WriterParameters(){WriteSymbols = TRUE,SymbolWriterProvider = debugWriterProvider}); 



任何想法,我怎么能这样做呢?


解决方案

我已经找到了解决办法。
的原因是真的很有趣。



Module.Import()方法必须从当前模块调用我们要修改,而不是模块的方法在哪里被定义为。它不是由原来的文档清晰。



有关例如,我们要添加在 Referenced.dll 组装定义为我们的 Main.dll 组装一些方法。然后,我们必须找到我们的 Main.dll 组装主模块,然后调用 MainModule.Import(methodFromReferencedAssembly);


Help me please with method import. I want to weave assembly and inject method call reference from base class defined in the other assembly (in fact it's the assembly where weaving code is defined).

private void InsertCallSetReference()
{
    //Get the load instruction to replace
    var ilProcessor = Property.SetMethod.Body.GetILProcessor();
    var argumentLoadInstructions = ilProcessor.Body.Instructions.ToList();

    MethodReference methodReference = ImportMethod("SetReference");

    foreach (var instruction in argumentLoadInstructions)
    {
        if (instruction.OpCode == OpCodes.Stfld)
        {
            ilProcessor.InsertAfter(instruction, ilProcessor.Create(OpCodes.Call, methodReference));
            ilProcessor.InsertAfter(instruction, ilProcessor.Create(OpCodes.Ldarg_1));
            ilProcessor.InsertAfter(instruction, ilProcessor.Create(OpCodes.Ldstr, DBFieldName));
            ilProcessor.InsertAfter(instruction, ilProcessor.Create(OpCodes.Ldarg_0));
            ilProcessor.Remove(instruction);
            break;
        }
    }
}

Method import code works just fine and returns method reference

private MethodReference ImportMethod(string name)
{
     var type = MongoConnectModule.Import(typeof(BaseDataObject));
     return MongoConnectModule.Import(type.Resolve().Methods.First(m => m.Name == name));
}

But after AssemblyDefinition Write call it throws me an error:

C:\dev\MongoConnect\WeavingTaskTest\Weaving\CodeWeaving.targets(32,5): error MSB4018: System.ArgumentException: Member 'System.Void MongoConnect.BaseDataObject::SetProperty(System.String,System.Object)' is declared in another module and needs to be imported

_assemblyDefinition.Write(_assemblyPath, new WriterParameters() { WriteSymbols = true, SymbolWriterProvider = debugWriterProvider });

Any idea how I could do that?

解决方案

I've found the solution. The reason was really funny.

Module.Import() method must be called from current module we want to modify, not the module where method is defined. It is not clear from original docs.

For example, we want to add some method defined in the Referenced.dll assembly to our Main.dll assembly. Then we have to find main module of our Main.dll assembly and then call MainModule.Import(methodFromReferencedAssembly);

这篇关于使用方法Mono.Cecil能做到进口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆