I have exception: Operation could destabilize the runtime , and i dont know why :(. Please Help me.
I Added Local, but still not working...
Method want to create dynamically (REF000001):
public static int REF000001(int REF000002, object REF000003, DateTime REF000004)
{
return (int)typeof(REF000005).GetMethod("REF000006", new Type[] { typeof(int), typeof(object), typeof(DateTime) }).Invoke(REF000005.REF000008(), new object[] { REF000002, REF000003, REF000004 });
}
This is class, which i want to invoke method from singleton.
public class REF000005
{
private static REF000005 REF000007;
private REF000005()
{
}
public static REF000005 REF000008()
{
if (REF000007 == null)
REF000007 = new REF000005();
return REF000007;
}
public int REF000006(int REF000009, object REF000010, DateTime REF000011)
{
return 5;
}
}
Return from ILDASM:
.method public hidebysig static int32 REF000001(int32 REF000002,
object REF000003,
valuetype [mscorlib]System.DateTime REF000004) cil managed
{
// Code size 118 (0x76)
.maxstack 5
.locals init ([0] int32 CS$1$0000,
[1] class [mscorlib]System.Type[] CS$0$0001,
[2] object[] CS$0$0002)
IL_0000: nop
IL_0001: ldtoken ConsoleApplication3.REF000005
IL_0006: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_000b: ldstr "REF000006"
IL_0010: ldc.i4.3
IL_0011: newarr [mscorlib]System.Type
IL_0016: stloc.1
IL_0017: ldloc.1
IL_0018: ldc.i4.0
IL_0019: ldtoken [mscorlib]System.Int32
IL_001e: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0023: stelem.ref
IL_0024: ldloc.1
IL_0025: ldc.i4.1
IL_0026: ldtoken [mscorlib]System.Object
IL_002b: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0030: stelem.ref
IL_0031: ldloc.1
IL_0032: ldc.i4.2
IL_0033: ldtoken [mscorlib]System.DateTime
IL_0038: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_003d: stelem.ref
IL_003e: ldloc.1
IL_003f: call instance class [mscorlib]System.Reflection.MethodInfo [mscorlib]System.Type::GetMethod(string,
class [mscorlib]System.Type[])
IL_0044: call class ConsoleApplication3.REF000005 ConsoleApplication3.REF000005::REF000008()
IL_0049: ldc.i4.3
IL_004a: newarr [mscorlib]System.Object
IL_004f: stloc.2
IL_0050: ldloc.2
IL_0051: ldc.i4.0
IL_0052: ldarg.0
IL_0053: box [mscorlib]System.Int32
IL_0058: stelem.ref
IL_0059: ldloc.2
IL_005a: ldc.i4.1
IL_005b: ldarg.1
IL_005c: stelem.ref
IL_005d: ldloc.2
IL_005e: ldc.i4.2
IL_005f: ldarg.2
IL_0060: box [mscorlib]System.DateTime
IL_0065: stelem.ref
IL_0066: ldloc.2
IL_0067: callvirt instance object [mscorlib]System.Reflection.MethodBase::Invoke(object,
object[])
IL_006c: unbox.any [mscorlib]System.Int32
IL_0071: stloc.0
IL_0072: br.s IL_0074
IL_0074: ldloc.0
IL_0075: ret
} // end of method Program::REF000001
My code with IL generator throw exception Operation could destabilize the runtime
static DynamicMethod Method1A()
{
DynamicMethod method1 = new DynamicMethod("Dodaj", typeof(void), new Type[] { typeof(int), typeof(object), typeof(DateTime) });
ILGenerator il = method1.GetILGenerator();
Label target = il.DefineLabel();
var tps = il.DeclareLocal(typeof(Type[]));
var obs = il.DeclareLocal(typeof(object[]));
il.Emit(OpCodes.Ldtoken, typeof(REF000005));
il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle", new Type[1] { typeof(RuntimeTypeHandle) }));
il.Emit(OpCodes.Ldstr, "REF000006");
il.Emit(OpCodes.Ldc_I4_3);
il.Emit(OpCodes.Newarr, typeof(Type));
il.Emit(OpCodes.Stloc, tps);
il.Emit(OpCodes.Ldloc, tps);
il.Emit(OpCodes.Ldc_I4_0);
il.Emit(OpCodes.Ldtoken, typeof(Int32));
il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle", new Type[1] { typeof(RuntimeTypeHandle) }));
il.Emit(OpCodes.Stelem_Ref);
il.Emit(OpCodes.Ldloc, tps);
il.Emit(OpCodes.Ldc_I4_1);
il.Emit(OpCodes.Ldtoken, typeof(Object));
il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle", new Type[1] { typeof(RuntimeTypeHandle) }));
il.Emit(OpCodes.Stelem_Ref);
il.Emit(OpCodes.Ldloc, tps);
il.Emit(OpCodes.Ldc_I4_2);
il.Emit(OpCodes.Ldtoken, typeof(DateTime));
il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle", new Type[1] { typeof(RuntimeTypeHandle) }));
il.Emit(OpCodes.Stelem_Ref);
il.Emit(OpCodes.Ldloc, tps);
il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetMethod", new Type[2] { typeof(string), typeof(Type[]) }));
il.Emit(OpCodes.Call, typeof(REF000005).GetMethod("REF000008"));
il.Emit(OpCodes.Ldc_I4_3);
il.Emit(OpCodes.Newarr, typeof(object));
il.Emit(OpCodes.Stloc, obs);
il.Emit(OpCodes.Ldloc, obs);
il.Emit(OpCodes.Ldc_I4_0);
il.Emit(OpCodes.Ldarg, 0);
il.Emit(OpCodes.Box, typeof(Int32));
il.Emit(OpCodes.Stelem_Ref);
il.Emit(OpCodes.Ldloc, obs);
il.Emit(OpCodes.Ldc_I4_1);
il.Emit(OpCodes.Ldarg, 1);
//il.Emit(OpCodes.Box, typeof(object));
il.Emit(OpCodes.Stelem_Ref);
il.Emit(OpCodes.Ldloc, obs);
il.Emit(OpCodes.Ldc_I4_2);
il.Emit(OpCodes.Ldarg, 2);
il.Emit(OpCodes.Box, typeof(DateTime));
il.Emit(OpCodes.Stelem_Ref);
il.Emit(OpCodes.Ldloc, obs);
il.Emit(OpCodes.Box, typeof(object[]));
il.Emit(OpCodes.Callvirt, typeof(MethodBase).GetMethod("Invoke", new Type[2] { typeof(object), typeof(object[]) }));
il.Emit(OpCodes.Unbox_Any, typeof(Int32));
il.Emit(OpCodes.Ret);
return method1;
}
There is a difference between the method you're copying and the one you're creating: the former returns
int, the lattervoid. Which is exactly why your code doesn't work: when you return from avoidmethod, the stack has to be empty; when you return from non-voidmethod, the stack has to contain the value to return (and nothing else).The best way to find out about this kind of issues is to create your method in a type in dynamic assembly, save that assembly to disk and then run PEVerify on it.
To fix this, you can change the return type of the method you're creating to
int. Another option would be to keep the methodvoid, butpopthe element on the stack right before youret.That being said, I really don't understand what you're trying to accomplish here. Your C# method already does exactly what you need, there is no need to use Reflection.Emit for that. And if you want to use Reflection.Emit to avoid the performance penalty of using reflection, you can't just use reflection from your IL.