2009-09-26 6 views
0

여러 가지 이유로 (안정성, 배포) 별도의 AppDomain에서 실행해야하는 .NET 코드가 있습니다. MBR에서 파생 된 프록시 객체를 생성하여 실제 객체에 대한 호출을 위임하므로 현재 AppDomain에로드되지 않습니다. 나는 일반적인 CreateInstanceAndUnwrap을 통해 프록시를 만든다. 나는 .NET 클라이언트에서 사용할 때COM interop에서 AppDomain을 사용하지 못했습니다.

this.eDirectCommunication = (EDirectCommunicationProxy) this.appDomain.CreateInstanceAndUnwrap(x, y); 

이 캐스트가 실패 COM 클라이언트에서로드 그러나 때, 잘 작동합니다. 투명한 프록시에서 전송하지 못했습니다. 필요한 유형이 원하는 AppDomain에 만들어 졌는지 확인하고 Unwrap이 성공하면 캐스트가 실패합니다. 흥미롭게도 두 AppDomain 모두 어셈블리 바인딩 실패를 가리키는 동일한 기본 디렉터리가있을 때 작동합니다. 그러나 Fusion 로그 뷰어에는 어떤 문제도 언급되어 있지 않습니다.

herehere 두 가지 유사한 질문이 있지만 답변을 제공하지 않습니다. 어떤 아이디어가 잘못되었거나 어떻게 디버깅 할 수 있습니까?

답변

1

몇 년 전이 정확한 문제가 발생했습니다. IIRC, 문제는 호출 스택이 두 개의 appdomain 경계를 넘어서서 관리 대상 객체에 대한 프록시가 두 번 마샬링되도록하는 것입니다 (COM-> default-> yours : 새 객체 : -> yours-> default). 일반적으로 문제는 아니지만 .NET COM 마샬 러의 QI에는 "안녕하세요, 저는 관리 객체이고 특별한 마샬링 동작이 필요합니다"라는 특수 인터페이스가 있습니다. (미안하지만, IID- ComTrace를 기억하지 않거나 IDispatch impl을 소유하고이를 CLR을 통해 마샬링하여 볼 수 있음). 이것이 기본 도메인에서 실행될 때 관리되는 것으로 인식하고 관리되는 유형을로드하려고 시도합니다.이 유형은 새 도메인의 기반이 기본과 동일 할 때만 성공합니다. 이것은 분명히 전체 목적을 무효로 만듭니다.

내가 처리 한 몇 가지 방법이 있습니다. 한 가지 방법은 객체 생성을 비동기로 만들어 관리 된 프록시를 새 도메인의 관리되지 않는 코드에 직접 푸시 할 수 있습니다 (예 : 관리되지 않는 콜백을 등록하고 기본 도메인을 우회하여 새 도메인에서 직접 호출). 이는 종단 간 모든 것을 제어하지 않는 추가 시나리오에서 분명히 까다 롭습니다.

다른 하나는 .NET 마샬 러가 "정말로 관리 대상입니까?"라는 질문에 응답하지 않은 바보 프록시를 굴려 놓은 관리되지 않는 코드 조각이있는 것입니다. 하지만 다른 모든 QIs와 IDispatch에 대한 모든 것을 다룰 것입니다. (나는 해킹을 IDispatch에만 제한하여 너무 쉽게 만들었습니다.) 새로운 순서는 다음과 같습니다 : COM-> default-> yours : 새로운 객체 -> 새로운 프록시 래퍼 -> 디폴트 -> COM.

주요 PITA- 향후 CLR 릴리스에서 가능한 몇 가지 수정 사항이 떠있는 CLR interop 팀의 사람이 블로그 게시물을 발견했지만 몇 년 전 이었지만 누구인지 기억이 안납니다. (죄송합니다, 나는 더 이상 삶을위한 interop을하지 않으며, 선량에게 감사합니다!)

관련 문제