从另一个AppDomain程序集中复制方法并从CurrentDomain执行它

时间:2014-06-22 11:25:45

标签: c# reflection.emit

在大图中我试图从主域中的dll执行方法,但之后,卸载该DLL。到目前为止,我已经创建了新AppDomain加载了Assembly \ dll,MarshalByRefObject我将方法的主体和MaxStackSize提取到主域,创建了{{} 1}},重新创建其中的主体并调用它。 但是当我调用它时,我得到了异常: DynamicMethod

获取并调用它的代码:

System.BadImageFormatException: Signature is not IMAGE_CEE_CS_CALLCONV_LOCAL_SIG

DynamicMethod method = new DynamicMethod( "func", typeof( void ), new Type[ 0 ] ); var info = method.GetDynamicILInfo( ); info.SetCode( marshal.GetILCode( ), marshal.GetMaxStackSize()); info.SetLocalSignature( SignatureHelper.GetMethodSigHelper( CallingConventions.Standard, typeof( void ) ).GetSignature( ) ); method.Invoke( null, new object[ 0 ] ); //<-- exception here Proxy类型的对象。 一些可能需要的说明:

  1. 我提取\调用的方法是marshal
  2. 尝试调用该方法的public static void Run();和加载dll \ assembly的AppDomain具有相同的引用。
  3. 修改

    我修改了签名,将第一个字节从AppDomain方法更改为0x07。 但是有新问题GetSignature

1 个答案:

答案 0 :(得分:2)

您的实现有一个很大的错误,来自MethodBase.GetMethodBody 的字节数组不可移植

使用OpCodes.CallOpCodes.Callvirt的方法调用会产生几个字节,一个指示调用类型(call / callvirt),后跟四个字节,表示元数据令牌。在这种情况下,此令牌可以解析为Int32并使用Module.ResolveMethod解析为MethodBase。

请注意,这些元数据令牌是在编译时生成的;它们可能在编译之间有所不同。 (虽然它是编译器的实现细节,但我相信它们只是基于编译期间看到的方法顺序的自动递增数字。)

这意味着您尝试使用的实际字节包含动态模块中无效的元数据令牌。他们可能会指出一种现有的方法,其签名不同于您期望的,或者可能根本不存在于您的模块中。

您需要解析您的il代码并再次发出所有内容,从而生成新的有效元数据标记。