gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 16:18:59 27 4
gpt4 key购买 nike

我正在用 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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com