2011-07-05 5 views
3

악몽 COM 상호 운용성이 무엇인지 입증하고 있습니다. WPF 창을 포함하는 단순 관리 DLL이 있습니다. 결국이 창을 시작하는 간단한 ViewController 클래스가 있지만 지금은 아무것도 수행하지 않는 빈 메서드가 있습니다.관리되는 DLL을 호출 할 때 COM Interop에서 EEMessageException을 throw하는 중

COM interop에 대해 등록 된 인터페이스를 제공하는 관리되는 DLL의 관리되는 래퍼를 만들었습니다. 내 관리되는 래퍼를 호출 할 수 있습니다. 내 관리되는 래퍼 DLL의 진입 점에 MessageBox를 표시 할 수 있습니다. 그러나 랩핑 오전 DLL에서이 ViewController 클래스에 어떤 메서드를 호출하려고하면이 얻을 :

MfcVSApp1.exe 0x7c812aeb (kernel32.dll) 첫 번째 예외 : Microsoft C++ 예외 : EEMessageException at 메모리 위치 0x0012cb30 ..

어제 모두 작동했습니다. 이제 몇 가지 코드 :

내 래퍼 엔티티 :

public class EphemerisViewController 
    {  
     public EphemerisViewController() 
     {   
     }     

     public void GetString() 
     { 
      MessageBox.Show("me"); 
     } 

    } 

이 DLL은 또한 등록 된 :

[Guid("83C799E0-9808-40c2-A1AB-80BCB77A3B18")] 
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] 
    [ComVisible(true)] 
    public interface IMaryln 
    { 
     void GetEphemeris(DateTime date, double latitude, double longitude); 

     /// <summary> 
     /// 
     /// </summary> 
     /// <param name="date"></param> 
     /// <param name="latitude"></param> 
     /// <param name="longitude"></param> 
     void GetEphemeris1(Int64 millSecsSince1970, double latitude, double longitude); 
    } 

[Guid("144DB386-D8EF-41a8-B9B1-57EE8A64600C")] 
    [ClassInterface(ClassInterfaceType.None)] 
    [ProgId("ManagedProxy.Maryln")] 
    [ComVisible(true)] 
    public class Maryln : IMaryln 
    { 
     #region IMaryln Members 

     public Maryln() 
     { 
      System.Diagnostics.Debugger.Launch(); 
     } 

     public void GetEphemeris(DateTime date, double latitude, double longitude) 
     { 
      //new EphemerisViewController().GetEphemeris(date, latitude, longitude); 
     } 

     public void GetEphemeris1(Int64 nanoSecsSince1970, double latitude, double longitude) 
     { 
      // This method does not throw. However, it will not be executed 
      // if any method in EphemerisViewController is called. 
      MessageBox.Show("Called from c++" + nanoSecsSince1970.ToString()); 


      try 
      { 
       //new Maryln().Test(); // this will not throw 
       new EphemerisViewController().GetString(); // this will 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message); 
      }        
     } 

     public void Test() 
     { 
      MessageBox.Show("maryln test"); 
     } 

     #endregion 
    } 

관리되는 DLL은 관리되는 래퍼 DLL에 의해 참조, UserControl이이의 ViewController를 포함 COM interop하지만 문제를 해결하지 못하면이 옵션의 선택을 취소했습니다. 구루 (Gurus) 선생님, 여기서 도움이 필요합니다. 이것은 이미 2 일의 근무일을 소비했으며 시작한 곳에서 3 걸음을 뒤로했습니다. 어제 모두 작동했습니다.

추가

다음과 같이 네이티브 클라이언트 내 래퍼를 소모 : 또한, 청소와 재건 한 솔루션을 여러 번하지만 행운

void CMfcVSApp1Doc::LaunchEphemrisDialog() 
{ 
    HRESULT hr; 
    CoInitialize(NULL); 
    try 
    {    
     ManagedProxy::IMarylnPtr maryln(__uuidof(ManagedProxy::Maryln));  
     LONG64 time = 1309897499216000000; 
     hr = maryln->GetEphemeris1(time, 0, 0); 
    } 
    catch(...) 
    { 

    } 
} 

.

답변

1

여기에 무슨 일이 있었는지 모르겠지만이 래퍼 DLL을 버리고 처음부터 새 것을 만들기로 결정했습니다. 나는이 두 프로젝트 중 어느 것이 문제를 일으키는 지 알기 위해 포장하고있는 C# 프로젝트를 변경하지 않았습니다. 이 행위만으로도 C# 프로젝트에 래핑 된 각 API를 디버깅 할 수있었습니다. Hans P가 제안한 프로젝트 디버그 기술을 사용하여 래퍼 DLL을 추가로 디버깅 할 수있었습니다. 나는 관리 된 예외를 볼 수 있다는 것을 큰숨로 쉬게했다. 확실히 앞으로 나아갈 수 있습니다.

EphemerisViewController에서 래핑 된 API를 호출 할 때마다 종속성을 찾을 수 없다는 관리 예외가 발생하는 것으로 나타났습니다 (어셈블리 매니페스트가로드 된 어셈블리 ....와 일치하지 않는 경우). 우리는이 모든 원인을 알고 있습니다.

위에서 언급 한 오류를 제거하여 어셈블리 참조를 정리 한 후 관리 DLL을 다시 호출 할 수있었습니다. 한 손에는 하루가 낭비되었습니다. 다른 한편으로 많은 것을 배웠습니다. 원래 래퍼가 작동을 멈춘 이유는 내 이해력을 넘어서는 것입니다. 그것은 네임 스페이스 손상과 DLL 로딩 문제의 조합 이었지만 누가 알았습니다.

나는 COM interop을 버리고 MFC로 다이빙을 할 준비가되어 있었지만, 나는 내 총에 붙어있어서 다행이다. C#과 비교하면, C++ 개발은 내가 염려하는 한 끔찍하다. 예를 들어 C#에서 일반적인 예외를 잡을 수있는 것은 C++에 대한 catch (...)와 동등한 이점이 있습니다. 간단한 변환을 수행하는 모든 미친 C++ 구문 및 헤드 긁기 루틴이 내 머리를 스핀들로 만듭니다. Intellisense, 오 인텔리 센스는 말할 것도 없습니다.만기 된 가상 어시 스 (Virtual Assist) 라이선스로 매일 휴면 상태에 빠지며 기업 예산이 부족한 상황에서, Boost와 같은 C++ 라이브러리를 조사 할 생각을 잠시 동안 C#에 집중할 것입니다. 그러나 소년, .NET으로 돌아와서 기쁘게 생각합니다.

나를 위해 여기에서 배운 교훈은 : COM interop을 사용하면 세부 사항에 세심한주의를 기울여야합니다!

관련 문제