繁体   English   中英

c#system.reflection.emit ldfld

[英]c# system.reflection.emit ldfld

您好我写了以下代码:

     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。 有人可以帮帮我吗?

这里似乎很可能以下是返回null

typeof(Form1).GetField("TextBox1", BindingFlags.Public | BindingFlags.NonPublic)

我的直接猜测是你需要在一组标志中添加一个BindingFlags.Instance来返回该字段。

这意味着调用的其中一个参数为null,很可能是typeof(Form1).GetField(“TextBox1”,BindingFlags.Public | BindingFlags.NonPublic)的返回值。

由于您已将该值存储在变量field1中 ,因此应进入调试模式并检查它是否为空。

如果值为null,则表示不同的含义:

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

在您的情况下,如果您查看GetField的MSDN文档 ,它明确指出:

以下BindingFlags过滤器标志可用于定义要包含在搜索中的字段:

您必须指定BindingFlags.Instance或BindingFlags.Static才能获得返回

指定BindingFlags.Public以在搜索中包含公共字段。

指定BindingFlags.NonPublic以在搜索中包含非公共字段(即私有,内部和受保护字段)。

指定BindingFlags.FlattenHierarchy以在层次结构中包含公共和受保护的静态成员; 不包括继承类中的私有静态成员。

所以你应该使用BindingFlags.Public | BindingFlags.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 });

另外,您不希望以您的方式检索属性访问器:您应该使用GetProperty而不是将GetMethod与访问者的名称(get_Text)一起使用:

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

希望有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM