1

我正在尝试使用操作码在生成的类中创建对代理方法的调用,我得到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 数组,然后返回类型。

4

1 回答 1

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);
    
于 2013-07-20T19:35:07.533 回答