发出代码工作不好

时间:2013-06-14 06:05:43

标签: c# .net reflection.emit

我正在尝试使用操作码在生成的类中创建对代理方法的调用,然后我得到ExecutionEngineException。此方法必须接收返回类型作为第一个参数和来自调用方法的参数数组。

var methodILGen = methodBuilder.GetILGenerator();
if (methodInfo.ReturnType != typeof(void))
{
 var method = typeBuilder.BaseType.GetMethod("proxyCaller");
 var args = methodInfo.GetParameters();
 var lb = methodILGen.DeclareLocal(methodInfo.ReturnType);  

 LocalBuilder _args = methodILGen.DeclareLocal(typeof(object[]));

 methodILGen.Emit(OpCodes.Ldc_I4_S, args.Length);
 methodILGen.Emit(OpCodes.Newarr, typeof(object));
 methodILGen.Emit(OpCodes.Stloc, _args);

 methodILGen.Emit(OpCodes.Ldloc, _args);
 for (int i = 0; i < args.Length; i++)
 {
  methodILGen.Emit(OpCodes.Ldc_I4_S, i);      
  methodILGen.Emit(OpCodes.Ldarg_S, i + 1);
  methodILGen.Emit(OpCodes.Stelem_Ref);
  methodILGen.Emit(OpCodes.Ldloc, _args);
 }
 methodILGen.Emit(OpCodes.Stloc, _args);

 methodILGen.Emit(OpCodes.Ldarg_0); // instance pointer
 methodILGen.Emit(OpCodes.Ldtoken, lb.LocalType); //return type
 methodILGen.Emit(OpCodes.Ldloc, _args); //args list

 methodILGen.Emit(OpCodes.Call, method);//, new Type[0]);

 if (methodInfo.ReturnType.IsValueType || methodInfo.ReturnType.IsEnum) methodILGen.Emit(OpCodes.Unbox_Any, lb.LocalType);
}
methodILGen.Emit(OpCodes.Ret);
typeBuilder.DefineMethodOverride(methodBuilder, methodInfo);

第二个问题是我首先收到一个args数组然后返回类型。

1 个答案:

答案 0 :(得分:4)

  1. 保存动态程序集,并使用PEVerify.exe进行检查。
  2. OpCodes.ldtoken不会将Type放在堆栈上。它放了RuntimeTypeHandle。要获得类型,你应该做类似的事情:

    var getTypeMethod = typeof (Type).GetMethod("GetTypeFromHandle");  
    methodILGen.Emit(OpCodes.Ldtoken, lb.LocalType);  
    methodILGen.Emit(OpCodes.Call, getTypeMethod);  
    methodILGen.Emit(OpCodes.Ldloc, _args);