我正在尝试创建一个简单的.NET编译器,以教育为目的。在解析、扫描并构建AST之后,我使用Reflection.Emit.ILGenerator
来生成.NET程序集。
以下是我用于生成程序集的示例代码:
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);
}
一切正常,这段代码生成了一个包含以下类的可执行文件:
using System;
public class Program
{
public Program()
{
}
public static void Main()
{
Console.WriteLine("Test!");
}
}
接下来我正在创建一个简单的第三方库,其中只有一个类,它构建成ThirdPartyLibrary.dll:
using System;
namespace ThirdPartyLibrary
{
public class MyPrint
{
public static void Print(string s)
{
Console.WriteLine("Third party prints: " + s);
}
}
}
现在我希望将
Console.WriteLine
方法调用替换为我的库中的MyPrint.Print
方法调用,并获得类似以下结果的代码:using System;
using ThirdPartyLibrary;
public class Program
{
public Program()
{
}
public static void Main()
{
MyPrint.Print("Test!");
}
}
据我所知,我必须读取我的
ThirdPartyLibrary.dll
文件,然后以某种方式反射它以获取其中的所有类型,然后才能使用MyPrint
类型。最后,我希望能够像使用csc.exe一样将路径引用作为我的Compiler.exe参数。因此问题是:
- 如何做到这一点?
- 所有这些都叫什么名字?(我不知道该搜索什么)
- 也许我应该使用其他框架来代替Reflection完成所有这些操作?
- 有其他建议吗...