c# - Reflection.Emit:AssemblyBuilder.SetEntryPoint 未设置入口点

标签 c# reflection.emit entry-point

我正在用 C# 编写一种连接语言,目前它是解释型的,但我想采取下一步:编译。首先,我尝试编写一个简单的“Hello,World!”使用 System.Reflection.Emit 编写发射器。该代码可以正常工作,没有任何 Emit 异常,但是当我运行生成的“test.exe”文件时,它会抛出异常

Unhandled Exception: System.MissingMethodException: Entry point not found in assembly 'IL_Test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.

我尝试用谷歌搜索答案,但没有成功。也许这里有人可以帮助我? (请)我编写的代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;
using System.IO;
using System.Diagnostics;

namespace ILCompileTest
{
    class Program
    {
        static void Main(string[] args)
        {
            const string ASSEMBLY_NAME = "IL_Test";

            AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(
                new AssemblyName(ASSEMBLY_NAME), AssemblyBuilderAccess.Save);
            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(
                ASSEMBLY_NAME);
            TypeBuilder typeBuilder = moduleBuilder.DefineType("Program", 
                TypeAttributes.Class | TypeAttributes.Public);
            MethodBuilder methodBuilder = typeBuilder.DefineMethod(
                "Main", MethodAttributes.Public | MethodAttributes.Static,
                typeof(void), new Type[] { typeof(string[]) });
            ILGenerator gen = methodBuilder.GetILGenerator();

            gen.Emit(OpCodes.Ldstr, "Hello, World!");
            gen.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
            gen.Emit(OpCodes.Ldc_I4_1);
            gen.Emit(OpCodes.Call, typeof(Console).GetMethod("ReadKey", new Type[] { typeof(bool) }));

            assemblyBuilder.SetEntryPoint(methodBuilder, PEFileKinds.ConsoleApplication);
            File.Delete("test.exe");
            assemblyBuilder.Save("test.exe");

            Process.Start("test.exe");
        }
    }
}

所以,问题是:如何设置我定义的 Main 方法的入口点?

最佳答案

您缺少对 typeBuilder.CreateType() 的调用, DefineDynamicModule 必须将 exe 名称作为第二个参数传递。 完整的工作示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;
using System.IO;
using System.Diagnostics;

namespace ILCompileTest
{
    class Program
    {
        static void Main(string[] args)
        {
            const string ASSEMBLY_NAME = "IL_Test";

            AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(
                new AssemblyName(ASSEMBLY_NAME), AssemblyBuilderAccess.Save);
            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(
                ASSEMBLY_NAME, "test.exe");
            TypeBuilder typeBuilder = moduleBuilder.DefineType("Program", 
                TypeAttributes.Class | TypeAttributes.Public);
            MethodBuilder methodBuilder = typeBuilder.DefineMethod(
                "Main", MethodAttributes.HideBySig|MethodAttributes.Public | MethodAttributes.Static,
                typeof(void), new Type[] { typeof(string[]) });
            ILGenerator gen = methodBuilder.GetILGenerator();

            gen.Emit(OpCodes.Ldstr, "Hello, World!");
            gen.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
            gen.Emit(OpCodes.Ldc_I4_1);
            gen.Emit(OpCodes.Call, typeof(Console).GetMethod("ReadKey", new Type[] { typeof(bool) }));
            typeBuilder.CreateType();
            assemblyBuilder.SetEntryPoint(methodBuilder, PEFileKinds.ConsoleApplication);
            File.Delete("test.exe");
            assemblyBuilder.Save("test.exe");

            Process.Start("test.exe");
        }
    }
}

关于c# - Reflection.Emit:AssemblyBuilder.SetEntryPoint 未设置入口点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15600142/

相关文章:

C# 使用 LINQ 和 Nullable Boolean

c# - 如何在后面的代码中使字符串加粗

c - 如何用gcc改变C程序的入口点?

c# - 如何使用 REST API 在 TFS 2015 中触发构建

c# - 有什么方法可以测试类似的属性吗?

c# - 反射(reflection) |发射|动态资源生成 - 使用 IResourceWriter.AddResource(key,value) 添加的资源值无法读取

c# - Reflection.Emit 如何分配不兼容的类型?

c# - 如何翻译新对象的创建?

docker - 在 docker run 中获取权限被拒绝

c - 如何在 OS X Mavericks 上使用 Clang 设置自定义 C 入口点?