在 .NET 中使用 Reflection.Emit 调用硬编码的现有方法
我正在使用 Reflection.Emit-Namespace 在运行时设计 .NET-Type。 目前,我即将生成一个方法,该方法调用生成类中已经存在的方法:
Dim AssemblyBuilder As AssemblyBuilder = Nothing
Dim ModuleBuilder As ModuleBuilder = Nothing
Dim TypeBuilder As TypeBuilder = Nothing
Dim MethodBuilder As MethodBuilder
Dim ReturnType As Type = Nothing
AssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(New AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.RunAndSave)
ModuleBuilder = AssemblyBuilder.DefineDynamicModule("DynamicAsssembly", "DynamicAssembly.dll")
TypeBuilder = ModuleBuilder.DefineType("DynamicType")
MethodBuilder = TypeBuilder.DefineMethod("Do", MethodAttributes.Public, Nothing, Nothing)
以上方法有效。
MethodBuilder.GetILGenerator.EmitCall(OpCodes.Call, Me.GetType.GetMethod("DisplayString"), Nothing)
MethodBuilder.GetILGenerator.Emit(OpCodes.Ret)
ReturnType = TypeBuilder.CreateType()
Activator.CreateInstance(ReturnType)
这是我想要做的一般事情:调用位于执行类本身的方法。但是当调用以下方法时,会抛出异常。
ReturnType.GetMethod("Do").Invoke(Activator.CreateInstance(ReturnType), Nothing)
内部异常是(类似于):InvalidProgramException,“公共语言运行时发现了一个无效程序。”
如果我用例如替换上面发出呼叫的行,
MethodBuilder.GetILGenerator.Emit(OpCodes.Ldstr, "test")
MethodBuilder.GetILGenerator.EmitCall(OpCodes.Call, GetType(System.Windows.Forms.MessageBox).GetMethod("Show", {GetType(String)}), {GetType(String)})
MethodBuilder.GetILGenerator.Emit(OpCodes.Pop)
它就可以正常工作。
我认为出现了问题,因为执行程序集类型及其成员不可访问,但这是真的吗?我可以更改什么来让它运行?
谢谢莫莫
I'm designing a .NET-Type at runtime by using the Reflection.Emit-Namespace.
Currently, I'm about to generate a method which invokes an already existing method in the generating class:
Dim AssemblyBuilder As AssemblyBuilder = Nothing
Dim ModuleBuilder As ModuleBuilder = Nothing
Dim TypeBuilder As TypeBuilder = Nothing
Dim MethodBuilder As MethodBuilder
Dim ReturnType As Type = Nothing
AssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(New AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.RunAndSave)
ModuleBuilder = AssemblyBuilder.DefineDynamicModule("DynamicAsssembly", "DynamicAssembly.dll")
TypeBuilder = ModuleBuilder.DefineType("DynamicType")
MethodBuilder = TypeBuilder.DefineMethod("Do", MethodAttributes.Public, Nothing, Nothing)
The above works.
MethodBuilder.GetILGenerator.EmitCall(OpCodes.Call, Me.GetType.GetMethod("DisplayString"), Nothing)
MethodBuilder.GetILGenerator.Emit(OpCodes.Ret)
ReturnType = TypeBuilder.CreateType()
Activator.CreateInstance(ReturnType)
This is want I want to do in general: Invoking a method which is located in the executing class itself. But when calling the following, an exeception is thrown.
ReturnType.GetMethod("Do").Invoke(Activator.CreateInstance(ReturnType), Nothing)
The inner exception is (something like): InvalidProgramException, "The Common Language Runtime has found an invalid program."
If I replace the lines from above in which I emit the call by e.g.
MethodBuilder.GetILGenerator.Emit(OpCodes.Ldstr, "test")
MethodBuilder.GetILGenerator.EmitCall(OpCodes.Call, GetType(System.Windows.Forms.MessageBox).GetMethod("Show", {GetType(String)}), {GetType(String)})
MethodBuilder.GetILGenerator.Emit(OpCodes.Pop)
it works fine.
I suppose there occures a problem because the executing assembly types and their members are not accessible, but is that true, and what may I change to get it running?
Thanks
Momo
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
DisplayString
是静态方法吗(MessageBox.Show
是)?如果没有,您将需要一个实例来调用该方法,
请提供我的损坏的 VB,已经有一段时间了;)
希望这会有所帮助。
了解需要发出什么内容的最佳方法之一是像平常一样编写类,然后在其上使用 IL DASM,然后您可以从中复制操作码。
Is
DisplayString
a static method (MessageBox.Show
is)?If not you are going to need an instance to call the method on
please for give my mangeled VB, its been quite a while ;)
hope this helps.
One of the best ways to learn what need to emit is to use write the class as you normally would, then use
IL DASM
on it, then you can copy the OpCodes from that.