4

我有一个动态方法,我有来自真实方法的 byte[](使用 Cecil)。现在如何将这个字节数组分配给动态方法并执行它?我确信这不仅仅是一种方式,必须有一种方式来调用字节数组。

4

4 回答 4

4

可能使用鲜为人知的静态方法:

MethodRental.SwapBody

一些条件适用,但应该完全符合您的需要:) 请参阅示例。

于 2012-08-21T09:53:40.120 回答
1

您将需要为此使用DynamicMethod。使用DynamicMethod.GetDynamicILInfo然后设置代码、局部变量和异常处理程序。您还需要修复出现在 IL 字节缓冲区中的任何标记。然后使用DynamicMethod.Invoke.

对于除了最微不足道的方法之外的所有方法,实现这一点都不是一件容易的事。

于 2012-08-21T09:41:44.960 回答
1

首先,您为什么不直接调用该方法而不进行任何复制?这应该比您尝试做的要简单得多。

基本上,你不能那样做。这是因为byte[]包含引用其他程序集或方法等内容的元数据标记。并且这些标记在每个程序集中都是不同的,即使它们代表相同的东西。因此,如果您只是尝试byte[]在另一个程序集中执行,元数据标记将是完全错误的。

您可以将其解析byte[]为它所代表的 IL 指令,并将元数据标记转换为具有它们的指令,但正确执行此操作可能需要大量工作。我相信塞西尔可以帮助你。

另一种选择可能是尝试将所有元数据令牌从旧程序集复制到新的动态程序集中,以便其中的令牌byte[]有效。但我不知道这是多么可行。

此外,如果该方法非常简单(没有调用方法并且没有使用自定义类型),那么只需复制byte[]应该可以工作。

于 2012-08-21T09:36:41.293 回答
0

你不能执行它:Cecil 是一个很好的工具,但它不适合需要在运行时逐个方法执行的代码。您应该为此使用 Reflection.Emit 。

请注意,建议的 SetCode() 方法不适用于您的情况,因为 Cecil 对元数据令牌的理解与运行时完全不同,因此运行时将无法解析令牌(例如用于方法调用)。

于 2012-08-21T06:18:39.970 回答