【问题标题】:Is it possible to invoke internal method from a dynamic method in .NET?是否可以从 .NET 中的动态方法调用内部方法?
【发布时间】:2009-11-22 05:34:05
【问题描述】:

我正在尝试从动态生成的方法中调用内部方法。 il 代码很简单:ldarg_0、callvirt、ret。

执行该方法失败,TypeLoadException 说它无法加载定义内部方法的类型。

当我想到它时,这似乎是合乎逻辑的,因为动态方法宿主程序集不是方法的声明类型程序集的朋友。

但是,我预计动态方法仍然可以工作,就像 Delegate.CreateDelegate 一样。毕竟,我确实设法获得了内部方法的 MethodInfo,所以权限障碍在我身后。

无论如何,问题是“是否可以从动态生成的方法中调用内部方法?”

谢谢。

编辑:

这是一个演示问题的简单代码示例:

using System;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;

namespace A
{
  internal class Data
  {
    internal string String { get; set; }
  }

  public static class Program
  {
    public static void Main()
    {
      Expression<Func<Data, string>> expr = x => x.String;
      var getterInfo = ((PropertyInfo)((MemberExpression)expr.Body).Member).GetGetMethod(true);
      var getter1 = (Func<Data, string>)Delegate.CreateDelegate(typeof(Func<Data, string>), getterInfo);
      var dm = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object) });
      var gen = dm.GetILGenerator();
      gen.Emit(OpCodes.Ldarg_0);
      gen.Emit(OpCodes.Castclass, typeof(Data));
      gen.Emit(OpCodes.Callvirt, getterInfo);
      gen.Emit(OpCodes.Ret);
      var getter2 = (Func<object, object>)dm.CreateDelegate(typeof(Func<object, object>));

      var data = new Data() { String = "Hello" };
      var str1 = getter1(data);
      var str2 = getter2(data);
    }
  }
}

在代码中,我创建了两个打开的实例委托来访问 Data.String 实例属性:

  • 使用 Delegate.CreateDelegate 键入安全的 getter1
  • 使用 DynamicMethod 键入不安全的 getter2

由 Delegate.CreateDelegate 创建的类型安全委托有效,而使用 DynamicMethod 的委托因 TypeLoadException 而失败。

请注意,我不希望采用类型安全的方法,因为创建 getter 的上下文不是通用的。当然,我可以解决这个问题,但现在的问题是委托人的问题 - 为什么 DynamicMethod 在 Delegate.CreateDelegate 成功的地方失败?

【问题讨论】:

  • A TypeLoadException 意味着找不到程序集 - 融合日志查看器说什么?
  • 融合日志为空。加载程序集应该没有问题。所有涉及的程序集都位于同一文件夹中。
  • @JeremyMcGee 是对的。在调试模式下获取 AppDomain 中已加载程序集的列表,并检查那里的目标程序集。另外,最好把你的代码放在这里检查一下。
  • 添加了一个简单的示例代码。谢谢大家。

标签: .net reflection.emit dynamic-method


【解决方案1】:

如果您跳过可见性检查,它将起作用。

改变这一行

var dm = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object) }, true);

参见msdn:(特别是包含所有规则的表格。)

这是来自构造函数的文档。

restrictedSkipVisibility 类型: System.Boolean true 跳过 JIT 类型和成员的可见性检查 由动态的 MSIL 访问 方法,有这个限制: 程序集的信任级别 包含这些类型和成员必须 等于或小于信托 发出 动态方法;否则为假。

【讨论】:

  • DynamicMethod 不在 .net 标准中,有什么方法可以在 .net 标准中做到这一点?
猜你喜欢
  • 1970-01-01
  • 2011-12-17
  • 2020-11-04
  • 2011-12-15
  • 2019-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多