1

こんにちは、私は次のコードを書きました:

     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)); で停止します。

教えてください: 値を null にすることはできません。パラメータ名: con . 誰かが私を助けることができますか?

4

2 に答える 2

2

ここでは、以下が返される可能性が非常に高いようですnull:

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

BindingFlags.Instance私の当面の推測では、フィールドを返すには、フラグのセットにa を追加する必要があると思います。

于 2012-12-10T12:12:02.293 に答える
2

これは、呼び出しのパラメーターの 1 つが null であることを意味し、おそらくtypeof(Form1).GetField("TextBox1", BindingFlags.Public | BindingFlags.NonPublic)の戻り値です。

その値はすでに変数field1に格納されているため、デバッグ モードに切り替えて、null でないことを確認する必要があります。

値が null の場合、別の意味になる可能性があります。

  • Form1 クラスに TextBox1 というフィールドが本当にありますか? 常にスペルと文字の大文字と小文字を再確認してください。GetField、GetProperty などのリフレクション メソッドでは、BindingFlags.IgnoreCase を使用しない限り、大文字と小文字が区別されます。
  • 提供した BindingFlags の値を使用してアクセスできますか (たとえば、静的ですか?)?

あなたの場合、GetFieldのMSDN ドキュメントを見ると、明示的に次のように述べられています。

次の BindingFlags フィルター フラグを使用して、検索に含めるフィールドを定義できます。

return を取得するには、BindingFlags.Instance または BindingFlags.Static のいずれかを指定する必要があります

検索に public フィールドを含めるには、BindingFlags.Public を指定します。

BindingFlags.NonPublic を指定して、非パブリック フィールド (つまり、プライベート、内部、および保護されたフィールド) を検索に含めます。

BindingFlags.FlattenHierarchy を指定して、パブリックおよび保護された静的メンバーを階層の上に含めます。継承されたクラスのプライベートな静的メンバーは含まれません。

したがって、 BindingFlags.Public |を使用する必要があります。BindingFlags.NonPublic | BindingFlags.Publicの代わりにBindingFlags.Instance | BindingFlags.NonPublic

こちらも交換

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

gen.Emit(OpCodes.Ldfld, field1);

そして、field1 を割り当てている行で適切なフラグを使用します。

更新: メインへの最後の呼び出しにも同じ問題があります。コードの前半で MethodAttributes を使用してメソッドを static として定義したため、次のコード行で BindingFlags.Static を指定する必要があります。

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;

それが役立つことを願っています。

于 2012-12-10T12:14:31.283 に答える