c# - OpCode.Call to Generic Method in different assembly using raw IL -
i want call generic method using raw il instructions. in order learn how using reflection.emit , experimenting dynamic assembly.
the method want make call following:
public class class1 { public void method1<t>() { console.writeline("classlibrary1.class1.method1<t>()"); } }
these instructions using
byte[] ilcodes = new byte[7]; ilcodes[0] = (byte)opcodes.ldarg_0.value; ilcodes[1] = (byte)opcodes.call.value; ilcodes[2] = (byte)(token & 0xff); ilcodes[3] = (byte)(token >> 8 & 0xff); ilcodes[4] = (byte)(token >> 16 & 0xff); ilcodes[5] = (byte)(token >> 24 & 0xff); ilcodes[6] = (byte)0x2a;
this method resides in diferent assembly , token see there obtained this:
int token = modulebuilder.getmethodtoken(typeof(classlibrary1.class1).getmethod("method1").getgenericmethoddefinition()).token;
i setting bytes methodbuilder.createmethodbody method. after set method body bytes, create assembly , call method, fails. when inspect generated code in reflector shows me method call lacking generic parameter
.method public hidebysig instance void method1<t>() cil managed { .maxstack 1 l_0000: ldarg.0 l_0001: call instance void [classlibrary1]classlibrary1.class1::method1() <-- should contain method1<!!t>() l_0006: ret }
how can generate parameter reference in order work? know how ilgenerator project mandatory raw instructions.
thank you.
edit: ildasm shows me (as @lasse suggested)
.method /*06000001*/ public hidebysig instance void method1<t>() cil managed // sig: 30 01 00 01 { // method begins @ rva 0x2050 // code size 7 (0x7) .maxstack 1 il_0000: /* 02 | */ ldarg.0 il_0001: /* 28 | (2b)000001 */ call instance void [classlibrary1/*23000002*/]classlibrary1.class1/*01000002*/::method1<!!0>() /* 2b000001 */ il_0006: /* 2a | */ ret } // end of method class1::method1
since ilgenerator
can this, looked @ what does. figured out need methodspec
token, that, need call several internal methods, above linked code (i used exposedobject make of reflection simpler):
int token = modulebuilder.getmethodtoken(typeof(class1).getmethod("method1")).token; signaturehelper sighelper = exposed.from(typeof(signaturehelper)) .getmethodspecsighelper(modulebuilder, new type[] { typeparameter }); var getsignatureparameters = new object[] { 0 }; byte[] bytes = (byte[])typeof(signaturehelper).getmethod( "internalgetsignature", bindingflags.nonpublic | bindingflags.instance) .invoke(sighelper, getsignatureparameters); int length = (int)getsignatureparameters[0]; var runtimemodule = exposed.from(modulebuilder).getnativehandle(); token = (int)typeof(typebuilder) .getmethod("definemethodspec", bindingflags.nonpublic | bindingflags.static) .invoke(null, new object[] { runtimemodule, token, bytes, length });
here, typeparameter
generictypeparameterbuilder
returned definegenericparameters
. using code, reflector shows following il, believe wanted (except made method1
static , replaced ldarg.0
nop
):
.method privatescope static void m2<u>() cil managed { .maxstack 16 l_0000: nop l_0001: call void [classlibrary1]class1::method1<!!u>() l_0006: ret }
Comments
Post a Comment