2014-06-22 4 views
3

큰 그림에서 주 도메인의 dll에서 메서드를 실행하려고하지만 그 후 해당 dll을 언로드합니다. 지금까지 나는 Assembly \ dll을 새로로드 한 AppDomain을 작성했으며 MarshalByRefObject I는 본체를 가져 왔으며 MaxStackSize이라는 기본 도메인에 메소드 DynamicMethod을 작성하고 내부에 본문을 다시 작성하여 호출했습니다. 하지만 호출 할 때 예외가 발생합니다. System.BadImageFormatException: Signature is not IMAGE_CEE_CS_CALLCONV_LOCAL_SIG.다른 AppDomain의 어셈블리에서 메서드를 복사하고 CurrentDomain에서 실행

가져와 그것을 호출하는 코드 :

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 

marshal 유형 Proxy의 개체입니다. 해야 할 수도 있습니다 일부 노트 :

  1. 내가 \의 호출을 가져 오는 오전 방법은 public static void Run();입니다.
  2. 메서드를 호출하려는 AppDomain과 DLL \ assembly를로드하는 AppDomain은 동일한 참조를 갖습니다.

편집

는 I는 GetSignature0x07 방법에서 상기 첫 번째 바이트를 변경하여 서명을 고정. 그러나 System.InvalidProgramException: Common Language Runtime detected an invalid program.

+2

다른 appdomain에서 메소드를 호출 할 수없는 이유는 무엇입니까? 코드 조각을 추출 할 수는 없습니다. 그것이 무엇에 달려 있는지 누가 압니까? 그것은 확실히 포함하는 어셈블리의 메타 데이터 테이블에 정확한 토큰 값에 따라 달라집니다. – usr

+0

@usr'AppDomain'을 언로드 한 후에도 코드가 새로운 객체를 생성해야하기 때문에 필요합니다. 그것은 그 dll 안에있는 것들에 의존하지 않습니다. 그냥 참조하십시오. 내가 다시 만들려고했던 코드는 다음과 같습니다 :'Console.WriteLine (AppDomain.CurrentDomain.FriendlyName); ' – KugBuBu

+0

GetMethodSigHelper()를 사용하는 것에 불평하고 있습니다. CallingConvention.Standard는 __stdcall 규칙을 사용하여 관리되지 않는 코드에만 유효합니다. 올바른 풍미가 어떤 모양인지 잘 모르겠다면 DynamicMethod.CreateDelegate()를 먼저 시도해보십시오. –

답변

1

귀하의 구현은 큰 잘못 MethodBase.GetMethodBody에서 바이트 배열을 가지고 새로운 문제가있다는 이식 할 수 없습니다.

OpCodes.Call 또는 OpCodes.Callvirt을 사용하는 메서드 호출은 몇 바이트로 이루어지며 하나는 호출 유형 (call/callvirt)과 메타 데이터 토큰을 나타내는 4 바이트를 나타냅니다. 이 토큰은이 경우 Int32로 구문 분석되고 Module.ResolveMethod을 사용하여 MethodBase로 해석 될 수 있습니다.

이러한 메타 데이터 토큰은 컴파일 타임에 생성됩니다. 그들은 편집간에 다를 수 있습니다. 컴파일러의 구현 세부 사항이지만 컴파일시 표시된 순서에 따라 자동 증가 된 수치라고 생각합니다.

즉, 사용하려는 실제 바이트에 메타 데이터 토큰이 포함되어 있음을 의미합니다. 동적 모듈에서는 유효하지 않습니다. 그들은 당신이 기대하는 것과 다른 서명을 가진 기존의 메소드를 가리킬 수도 있고, 모듈에 전혀 존재하지 않을 수도 있습니다.

il-code를 구문 분석하고 모든 것을 다시 내보내고 새롭고 유효한 메타 데이터 토큰을 생성해야합니다.