gpt4 book ai didi

C# 从 IL 中的静态方法调用并返回一个对象

转载 作者:行者123 更新时间:2023-12-04 13:02:52 25 4
gpt4 key购买 nike

这是对所提供解决方案的扩展 here .我创建了一个返回对象的静态方法。我的目标是为我在运行时定义的类型编写动态方法,以返回该静态方法返回的对象。到目前为止我的代码:

 // type builder and other prep stuff removed for sake of space and reading

private void EmitReferenceMethodBody(Type returnType)
{
MethodBuilder builder =
typeBuilder.DefineMethod(
method.Name,
MethodAttributes.Virtual | MethodAttributes.Public,
method.CallingConvention,
method.ReturnType,
typeArray1);
builder.InitLocals = true;
ILGenerator gen = builder.GetILGenerator();
MethodInfo getStoredObject = typeof(ObjectStore).GetMethod("GetStoredObject", BindingFlags.Public | BindingFlags.Static);
MethodInfo getTypeFromHandle = typeof(Type).GetMethod("GetTypeFromHandle");

gen.Emit(OpCodes.Ldtoken, returnType);
gen.Emit(OpCodes.Call, getTypeFromHandle);
gen.Emit(OpCodes.Call, getStoredObject);
gen.Emit(OpCodes.Ret);
}

更新后的代码现在调用该方法,但似乎传递的是动态创建类型的类型,而不是变量 returnType。

最佳答案

至少有一个问题是您将“this”引用 (OpCodes.Ldarg_0) 压入堆栈,即使它从未弹出(因为您正在调用一个static 方法)。我会尝试删除该行,看看它是否表现更好。

另一个问题是您将 new Type[] { returnType } 传递给 EmitCall 方法。这是为可选参数 (params) 而设计的,我怀疑您的方法实际上没有任何参数。因此,您也应该删除该参数。

编辑:

根据评论,您正试图将静态已知的 System.Type 对象传递给您正在动态调用的方法。这是可能的,但您需要跳过几个环节。

  1. 为方法 Type.GetTypeFromHandle 获取对 MethodInfo 的引用:

    MethodInfo getTypeFromHandle = typeof(Type).GetMethod("GetTypeFromHandle");
  2. 使用以下 IL 行将您的 returnType 压入堆栈:

    gen.Emit(OpCodes.Ldtoken, returnType);
    gen.Emit(OpCodes.Call, getTypeFromHandle);

总而言之,您的代码应如下所示:

MethodInfo getTypeFromHandle = typeof(Type).GetMethod("GetTypeFromHandle");
gen.Emit(OpCodes.Ldtoken, returnType);
gen.Emit(OpCodes.Call, getTypeFromHandle);
gen.EmitCall(OpCodes.Call, getStoredObject);
gen.Emit(OpCodes.Ret);

这段代码的过渡堆栈行为是:

  1. 使用Opcodes.Ldtoken将指定Type引用对应的RuntimeTypeHandle压入堆栈。

  2. 调用 getTypeFromHandle 将类型句柄弹出堆栈,并将实际的 System.Type 压入堆栈。

  3. 调用您的静态方法,这会将 Type 参数从堆栈中弹出,并将您自己的方法的返回值压入堆栈。

  4. 从方法返回。

关于C# 从 IL 中的静态方法调用并返回一个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9623797/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com