简体   繁体   English

Reflection.Emit.ILGenerator :: Emit,来自第三方.net库的调用方法

[英]Reflection.Emit.ILGenerator::Emit, call method from third party .net library

I'm trying to create simple .net compiler for educational purposes. 我正在尝试为教育目的创建简单的.net编译器。 After parsing, scanning and building AST I'm generating .net assembly using Reflection.Emit.ILGenerator . 解析,扫描和构建AST后,我使用Reflection.Emit.ILGenerator生成.net程序集。

Here is my sample code for assembly generation: 这是我的程序集生成示例代码:

static void Main(string[] args)
{
    string moduleName = "Test.exe";

    AssemblyName assemblyName = new AssemblyName(Path.GetFileNameWithoutExtension(moduleName));
    AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save);
    ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(moduleName);
    TypeBuilder typeBuilder = moduleBuilder.DefineType("Program", TypeAttributes.Public);
    MethodBuilder mainMethod = typeBuilder.DefineMethod(
        "Main", MethodAttributes.Public | MethodAttributes.Static, typeof(void), System.Type.EmptyTypes);


    ILGenerator il = mainMethod.GetILGenerator();

    il.Emit(OpCodes.Ldstr, "Test!");
    il.Emit(OpCodes.Call, typeof(System.Console).GetMethod("WriteLine", new System.Type[] { typeof(string) }));
    il.Emit(OpCodes.Ret);

    typeBuilder.CreateType();
    moduleBuilder.CreateGlobalFunctions();
    assemblyBuilder.SetEntryPoint(mainMethod);
    assemblyBuilder.Save(moduleName);
}

Everything works fine, this code generates executable with following class: 一切正常,这段代码生成以下类的可执行文件:

using System;

public class Program
{
    public Program()
    {
    }

    public static void Main()
    {
        Console.WriteLine("Test!");
    }
}

Next I'm creating simple third party library with single class which builds to ThirdPartyLibrary.dll: 接下来,我正在使用构建到ThirdPartyLibrary.dll的单个类创建简单的第三方库:

using System;

namespace ThirdPartyLibrary
{
    public class MyPrint
    {
        public static void Print(string s)
        {
            Console.WriteLine("Third party prints: " + s);
        }
    }
}

Now I wish to replace Console.WriteLine method call to MyPrint.Print method call from my library and get result code something like: 现在我希望将Console.WriteLine方法调用替换为来自我的库的MyPrint.Print方法调用,并获得如下结果代码:

using System;
using ThirdPartyLibrary;

public class Program
{
    public Program()
    {
    }

    public static void Main()
    {
        MyPrint.Print("Test!");
    }
}

As far as I understand I must read my ThirdPartyLibrary.dll file, then reflect it somehow to get all types from it and then it will be possible to use MyPrint type. 据我所知,我必须阅读我的ThirdPartyLibrary.dll文件,然后以某种方式反映它以从中获取所有类型,然后就可以使用MyPrint类型。 Finally I wish to be able to path references as myCompiler.exe arguments like using csc.exe. 最后,我希望能够像使用csc.exe一样将引用路径作为myCompiler.exe参数。

So the questions are: 所以问题是:

  • How to do it? 怎么做?
  • How all this named? 这一切如何命名? (I can't understand what to google) (我无法理解google的内容)
  • May be I should use some other frameworks, instead of Reflection to do all this? 可能是我应该使用其他一些框架,而不是反射来做所有这些?
  • Any other suggestions... 任何其他建议......

The only change here is the target method: 这里唯一的变化是目标方法:

var targetMethod = Assembly.LoadFrom("ThirdPartyLibrary.dll")
    .GetType("ThirdPartyLibrary.MyPrint")
    .GetMethod("Print", new [] {typeof(string)});
...
il.Emit(OpCodes.Ldstr, "Test!");
il.Emit(OpCodes.Call, targetMethod);
il.Emit(OpCodes.Ret);

So instead of using Console.WriteLine , we call MyPrint.Print . 因此,我们不使用Console.WriteLine ,而是调用MyPrint.Print

  • How to do it? 怎么做? A: like the above 答:喜欢上述内容
  • How all this named? 这一切如何命名? A: IL-generation, meta-programming, reflection 答:IL生成,元编程,反射
  • May be I should use some other frameworks, instead of Reflection to do all this? 可能是我应该使用其他一些框架,而不是反射来做所有这些? A: reflection covers most scenarios; 答:反思涵盖了大多数情景; I use IKVM.Reflection.dll in a few places, because it allows me to do cross-framework targeting, but you probably don't need that. 我在一些地方使用IKVM.Reflection.dll ,因为它允许我进行跨框架定位,但你可能不需要它。 What you might find handy is Sigil , which takes away a lot of the pain of IL-generation (unbalanced stacks, etc) by giving you sane error reports at the time you generate (rather than when you execute). 可能会发现什么方便的是Sigil ,它通过在您生成时(而不是在执行时)为您提供合理的错误报告来消除IL生成(不平衡堆栈等)的许多痛苦。 Mono.Cecil is also interesting Mono.Cecil也很有趣

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM