, . " " , IL DynamicMethod, 32- 64- .
, , , , /
, GCHandle; GC , , . , GCHandle, , DynamicMethod ( ) . GCHandle, , / .
, GCHandle (.. ) . , . , , , , / DynamicMethod, ; GCHandle (, ) , .
public static void Emit_LdInst<TInst>(this ILGenerator il, TInst inst)
where TInst : class
{
var gch = GCHandle.Alloc(inst);
var ptr = GCHandle.ToIntPtr(gch);
if (IntPtr.Size == 4)
il.Emit(OpCodes.Ldc_I4, ptr.ToInt32());
else
il.Emit(OpCodes.Ldc_I8, ptr.ToInt64());
il.Emit(OpCodes.Ldobj, typeof(TInst));
}
, , , Opcodes.Ldobj, Type , . , . bool, , System.Type , , true, Opcodes.Ldobj , .
TInst _inst = new MyObject();
il.Emit_LdInst(_inst);
il.Emit(OpCodes.Isinst, typeof(TInst));
il.Emit(OpCodes.Ldnull);
il.Emit(OpCodes.Ceq);
il.Emit(OpCodes.Ldc_I4_1);
il.Emit(OpCodes.Xor);
Ldc_I4/Ldc_I8 shove is Conv_I, , IntPtr.Size Ldc_I8 a long, x86. Opcodes.Ldobj .
. ( DynamicMethod), - . true, . ( , ...)
il.Emit_LdInst(cmp);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ceq);
, where TInst : class , . -, , . , , , Opcodes.Ldobj, , , , . , , - , 32 64 , . , a ValueType.
I tested all of this quite extensively on both x86 and x64 , debugging and releasing, and it works great without any problems. >