时间:2019-03-08 标签:c#system.reflection.emitldfld

标签 c# .net reflection.emit

你好,我写了下面的代码:

     AssemblyName assemblyName = new AssemblyName("SamAsm");
        AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
        TypeBuilder typeBuilder = assemblyBuilder.DefineDynamicModule("SamAsm.exe").DefineType("SamAsmType", TypeAttributes.Public);
        MethodBuilder methodBuilder1 = typeBuilder.DefineMethod("Main", MethodAttributes.Static | MethodAttributes.Public, typeof(void), new Type[] { typeof(string) });
        ILGenerator gen = methodBuilder1.GetILGenerator();
        FieldInfo field1 = typeof(Form1).GetField("TextBox1", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

        MethodInfo method2 = typeof(Control).GetProperty("Text", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).GetGetMethod();
        MethodInfo method3 = typeof(String).GetMethod(
            "op_Equality",
            BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic,
            null,
            new Type[]{
    typeof(String),
    typeof(String)
    },
            null
            );
        MethodInfo method4 = typeof(MessageBox).GetMethod(
            "Show",
            BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic,
            null,
            new Type[]{
    typeof(String)
    },
            null
            );



        LocalBuilder a = gen.DeclareLocal(typeof(Boolean));

        System.Reflection.Emit.Label label42 = gen.DefineLabel();

        gen.Emit(OpCodes.Nop);
        gen.Emit(OpCodes.Ldarg_0);
        gen.Emit(OpCodes.Ldfld, field1);
        gen.Emit(OpCodes.Callvirt, method2);
        gen.Emit(OpCodes.Ldstr, "HI");
        gen.Emit(OpCodes.Call, method3);
        gen.Emit(OpCodes.Ldc_I4_0);
        gen.Emit(OpCodes.Ceq);
        gen.Emit(OpCodes.Stloc_0);
        gen.Emit(OpCodes.Ldloc_0);
        gen.Emit(OpCodes.Brtrue_S, label42);
        gen.Emit(OpCodes.Nop);
        gen.Emit(OpCodes.Ldstr, "You cracked me");
        gen.Emit(OpCodes.Call, method4);
        gen.Emit(OpCodes.Pop);
        gen.Emit(OpCodes.Nop);
        gen.MarkLabel(label42);
        gen.Emit(OpCodes.Ret);




        typeBuilder.CreateType().GetMethod("Main").Invoke(null, new string[] { null });
        assemblyBuilder.SetEntryPoint(methodBuilder1, PEFileKinds.WindowApplication);}

当我尝试这个时,它阻止了我 gen.Emit(OpCodes.Ldfld,typeof(Form1).GetField("TextBox1", BindingFlags.Public | BindingFlags.NonPublic));

并告诉:该值不能为空。参数名称:con。 有人可以帮助我吗?

最佳答案

这意味着调用的参数之一为空,很可能是 typeof(Form1).GetField("TextBox1", BindingFlags.Public | BindingFlags.NonPublic) 的返回值

因为您已经将该值存储在变量 field1 中,您应该进入 Debug模式并检查它是否不为空。

如果值为 null,它可能意味着不同的事情:

  • 在您的 Form1 类中是否真的有一个名为 TextBox1 的字段?始终仔细检查拼写和字符大小写。 GetField、GetProperty 等反射方法区分大小写,除非与 BindingFlags.IgnoreCase 一起使用。
  • 是否可以使用您提供的 BindingFlags 的值访问它(例如,它是静态的吗?)?

在您的情况下,如果您查看 MSDN documentation对于 GetField,它明确指出:

The following BindingFlags filter flags can be used to define which fields to include in the search:

You must specify either BindingFlags.Instance or BindingFlags.Static in order to get a return.

Specify BindingFlags.Public to include public fields in the search.

Specify BindingFlags.NonPublic to include non-public fields (that is, private, internal, and protected fields) in the search.

Specify BindingFlags.FlattenHierarchy to include public and protected static members up the hierarchy; private static members in inherited classes are not included.

所以你应该使用BindingFlags.Public |绑定(bind)标志.NonPublic | BindingFlags.Instance 而不是 BindingFlags.Public | BindingFlags.NonPublic

也替换

gen.Emit(OpCodes.Ldfld,typeof(Form1).GetField("TextBox1", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance));

gen.Emit(OpCodes.Ldfld, field1);

并在分配 field1 的行上使用正确的标志。

更新:您在最后一次调用 Main 时遇到了同样的问题。您需要在以下代码行中指定 BindingFlags.Static,因为您在代码的前面使用 MethodAttributes 将方法定义为静态:

typeBuilder.CreateType().GetMethod("Main", BindingFlags.Static | BindingFlags.Public).Invoke(null, new string[] { null });

另外,您不希望以您现在的方式检索属性访问器:与其使用带有访问器名称 (get_Text) 的 GetMethod,不如使用 GetProperty:

    MethodInfo method2 = typeof(Control).GetProperty("Text", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).GetMethod;

希望对您有所帮助。

关于时间:2019-03-08 标签:c#system.reflection.emitldfld,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13783063/

相关文章:

c# - 如何在我的 ASP.NET 菜单中使用 BreadCrumb 的 Bootstrap 风格?

c# - 从控制台运行 dotnet 核心应用程序时无法解决依赖关系

.net - BackgroundWorker.RunWorkerCompleted 线程安全吗

c# - 使用 Inno Setup 安装具有不同配置的同一 Windows 服务的多个实例

c# - 如何将 IL 翻译成 Emit 语句?

c# - 如何发出静态外部方法?

c# - 在数据库中存储动态JSON数据并通过键值搜索

c# - Debug.Writeline 不打印任何东西

c# - 获取通用枚举的基础值

c# - 创建 DynamicMethod 为属性赋值?