C# 通过Emit(Opcodes.Call,methodinfo)创建类型的实例
我正在使用反射和ilGenerator创建一个.Exe,从DLL调用一个方法 我的问题是,当它是一个实例方法时,我必须在调用该方法之前将实例放入堆栈中。因此,我在C#中有一个方法,它创建并返回这个实例。它正在抛出C# 通过Emit(Opcodes.Call,methodinfo)创建类型的实例,c#,reflection,cil,il,C#,Reflection,Cil,Il,我正在使用反射和ilGenerator创建一个.Exe,从DLL调用一个方法 我的问题是,当它是一个实例方法时,我必须在调用该方法之前将实例放入堆栈中。因此,我在C#中有一个方法,它创建并返回这个实例。它正在抛出System.MethodAccessException 我的问题是,这可能吗?它是如何工作的?通过在IL中执行此操作,IL.Emit(Opcodes.call,methodInfo),在创建.exe的调用中,在运行时,它如何知道要调用哪个方法?我要调用的方法是否转到.exe程序集?我对
System.MethodAccessException
我的问题是,这可能吗?它是如何工作的?通过在IL中执行此操作,IL.Emit(Opcodes.call,methodInfo)
,在创建.exe的调用中,在运行时,它如何知道要调用哪个方法?我要调用的方法是否转到.exe程序集?我对此感到非常困惑
我转到DLL,获取类型,获取我要调用的MethodInfo
。
我创建了一个新的程序集->组装生成器->模块生成器->类型生成器我创建的这个新类型是从DLL扩展类型:
TypeBuilder tb = mb.DefineType("TypeApp" + typeName, baseType.Attributes, DLLType);
我创建MethodBuilder
作为新类型的入口点:
MethodBuilder metb = tb.DefineMethod("Main", MethodAttributes.Public |
MethodAttributes.Static, typeof(void), argsArray);
ab.SetEntryPoint(metb);
然后我为Main
方法生成IL:
ILGenerator il = metb.GetILGenerator();
il.Emit(OpCodes.Call, callcreateInstanceMethodInfo);
IL还在继续,但到目前为止我还不完全理解
然后我创建.exe
tb.CreateType();
ab.Save(typeName + methodName + ".exe");
它正在抛出System.MethodAccessException
您是否尝试调用对生成的类型通常不可见的方法(调用私有或内部方法,调用不从其继承的类中的受保护方法)。我相信禁用验证是可能的,但这会增加代码的安全性要求,如果需要在部分信任环境中运行,这是一个问题
在创建.exe的调用中,当处于运行时,它如何知道要调用哪个方法
发出的IL包含一个4字节的元数据令牌,这本质上是对所生成模块中一个元数据表(MethodDef或MemberRef表)中记录的引用。如果它是MethodDef标记,那么它是对方法定义的直接引用;如果它是MemberRef标记,那么它将提供足够的信息来标识要调用的正确程序集/类/方法
显示的生成IL的代码表示您正在使用调用操作码。如果您正在调用虚拟方法,那么应该改用callvirt(虽然您可以对非抽象方法使用调用,但这将导致调用特定的实现…即使它被重写,这也可能是意外的,我在某处读到,对另一个对象的虚拟方法使用调用时增加了安全要求).向下投票人:请发表评论。你能展示一下你正在做什么来获得
MethodAccessException
?我很难按照问题中的描述进行操作。是的,你可以向下投票,但至少要说明原因,我现在要编辑为你的问题创建高级代码,编译它,然后使用类似的工具查看生成的IL。