Volání pevně existující metodu s Reflection.Emit v .NET

hlasů
1

Jsem navrhování .NET typ za běhu pomocí Reflection.Emit-namespace. V současné době, Chystám se vygeneruje metodu, která vyvolá již existující metodu ve třídě generující:

Dim AssemblyBuilder As AssemblyBuilder = Nothing
Dim ModuleBuilder As ModuleBuilder = Nothing
Dim TypeBuilder As TypeBuilder = Nothing

Dim MethodBuilder As MethodBuilder
Dim ReturnType As Type = Nothing

AssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(New AssemblyName(DynamicAssembly), AssemblyBuilderAccess.RunAndSave)

ModuleBuilder = AssemblyBuilder.DefineDynamicModule(DynamicAsssembly, DynamicAssembly.dll)
TypeBuilder = ModuleBuilder.DefineType(DynamicType)

MethodBuilder = TypeBuilder.DefineMethod(Do, MethodAttributes.Public, Nothing, Nothing)

Výše uvedené práce.

MethodBuilder.GetILGenerator.EmitCall(OpCodes.Call, Me.GetType.GetMethod(DisplayString), Nothing)
MethodBuilder.GetILGenerator.Emit(OpCodes.Ret)

ReturnType = TypeBuilder.CreateType()
Activator.CreateInstance(ReturnType)

To je chtějí chci dělat obecně: Vyvolání metody, která se nachází v samotném vykonávajícím třídě. Ale když volá následující, An exeception je vyvolána.

ReturnType.GetMethod(Do).Invoke(Activator.CreateInstance(ReturnType), Nothing)

Vnitřní Výjimku tvoří (něco jako): InvalidProgramException The Common Language Runtime nalezl neplatný program.

Kdybych nahradit linky shora, ve kterém jsem se vysílají výzvu např

MethodBuilder.GetILGenerator.Emit(OpCodes.Ldstr, test)
MethodBuilder.GetILGenerator.EmitCall(OpCodes.Call, GetType(System.Windows.Forms.MessageBox).GetMethod(Show, {GetType(String)}), {GetType(String)})
MethodBuilder.GetILGenerator.Emit(OpCodes.Pop)

to funguje dobře.

Myslím, že tam vyskytuje problém, protože vykonávající typy montážních a jejich členové nejsou přístupné, ale je to pravda, a co mohu změnit, aby si to běží?

dík

Momo

Položena 15/11/2011 v 01:09
zdroj uživatelem
V jiných jazycích...                            


1 odpovědí

hlasů
0

Je DisplayStringstatická metoda ( MessageBox.Show je)?

Pokud tomu tak není budete potřebovat instanci volání metody na

prosím o dávám mangeled VB, jeho docela nějakou dobu)

dim fieldBuilder as FieldBuilder = typeBuilder.DefineField(
                "o", Me.GetType(),
                 FieldAttributes.InitOnly | FieldAttributes.Private);


dim constructor as ConstructorBuilder = typeBuilder.DefineConstructor(
                MethodAttributes.Public |
                MethodAttributes.HideBySig |
                MethodAttributes.SpecialName |
                MethodAttributes.RTSpecialName,
                CallingConventions.Standard, new[] { Me.GetType() });

//Make tho CTOR for the dynamic type, it needs to take an argument of the
//instance to call the method on (in this case it will be Me)

dim il as ILGenerator = constructor.GetILGenerator();

il.Emit(OpCodes.Ldarg_0);

il.Emit(OpCodes.Call, baseCtor);

il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Stfld, fieldBuilder);

il.Emit(OpCodes.Ret);

// Make the method
il = methodBuilder.GetILGenerator();

il.Emit(OpCodes.Ldarg, 0);
il.Emit(OpCodes.Ldfld, fieldBuilder);
il.Emit(OpCodes.Ldstr, 'test');

il.Emit(OpCodes.Callvirt, Me.GetType.GetMethod ...
il.Emit(OpCodes.Ret);

snad to pomůže.

Jedním z nejlepších způsobů, jak zjistit, co je potřeba, aby vydávaly je použít psát třídu jako obvykle by, pak použijte IL DASMna něj, pak si můžete zkopírovat opcodes z toho.

Odpovězeno 15/11/2011 v 03:28
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more