【发布时间】:2013-05-07 13:37:12
【问题描述】:
我正在尝试为教育目的创建简单的 .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 一样将路径引用作为 myCompiler.exe 参数。
所以问题是:
- 怎么做?
- 这一切是怎么命名的? (我不明白用谷歌搜索什么)
- 也许我应该使用其他一些框架而不是反射来完成这一切?
- 任何其他建议...
【问题讨论】:
标签: c# .net compiler-construction reflection.emit