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

Popular posts from this blog

javascript - Using jquery append to add option values into a select element not working -

Android soft keyboard reverts to default keyboard on orientation change -

Rendering JButton to get the JCheckBox behavior in a JTable by using images does not update my table -