如何从字节数组(在内存中)运行方法?

时间:2012-08-20 14:12:25

标签: c# .net reflection mono mono.cecil

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

4 个答案:

答案 0 :(得分:4)

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

MethodRental.SwapBody

某些条件适用,但应该完全符合您的要求:)参见示例。

答案 1 :(得分:1)

首先,为什么不在不进行任何复制的情况下调用该方法?这应该比你想做的要简单得多。

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

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

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

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

答案 2 :(得分:1)

您需要使用DynamicMethod。使用DynamicMethod.GetDynamicILInfo,然后设置代码,局部变量和异常处理程序。您还需要修复IL字节缓冲区中出现的任何令牌。然后使用DynamicMethod.Invoke调用。

对于除了最简单的方法之外的所有方法,实现这一目标并非易事。

答案 3 :(得分:0)

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

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