2009-11-12 5 views
6

나는 COM에 정렬 화를 구현하는 세 가지 방법이있어 그것을 얻을으로 :COM은 인터페이스를 마샬링하는 방법을 어떻게 선택합니까?

  • 형식 라이브러리 마샬링
  • 프록시/스텁 마샬링 어떻게하는지

이제 객체에 의해 IMarshal을 구현

  • 구성 요소 소비자 (사용자) 어느 것이 사용됩니까? 자체적으로 결정하고 선호하는 방법을 사용합니까? 아니면 내장 함수를 호출하고 문제를 해결합니까?

    현재 다음과 같은 경험이 있습니다. 내 구성 요소는 다른 회사의 구성 요소에 의해 구현 된 사용자 지정 인터페이스 ICustomInterface을 구현합니다. 내 구성 요소에 typelib이없고 IMarshal이 구현되어 있지 않습니다. 시스템 레지스트리에는 HKCR \ Interface {uuidof (ICustomInterface)} \ ProxyStubClsid32 키가 있으며 다른 회사에서 제공하는 라이브러리로 추적 할 수있는 프록시/스텁의 GUID가 있습니다.

    이제 내 구성 요소 소비자가 내 구성 요소를 초기화 할 때 내 구성 요소에서 IMarshal을 요청하는 QueryInterface()를 호출하고 E_NOINTERFACE가 반환되면 아무것도 수행하지 않습니다. 왜 이것이 다른 회사의 프록시/스텁 라이브러리가 시작되지 않는 이유입니까?

  • 답변

    0

    약간 녹슬었지만 프로젝트에 blindquery라는 함수가 있습니까? (보통 C++ ATL 프로젝트를 만든 경우 마법사에 의해 선언됩니다). 함수 내부의 중단 점. 마법사가 생성하는 함수는 버그가있는 코드로 인해 E_NOINTERFACE를 반환하는 쿼리 인터페이스에 자주 문제가 있습니다.

    내 옛날 프로젝트 _에서

    편집 (찾을 샘플 코드) blindquery

    class ATL_NO_VTABLE CChildEvents : 
        public CComObjectRootEx <CComSingleThreadModel>, 
        public CComCoClass<CChildEvents, &CLSID_ChildEvents>, 
        public IDispatchImpl<IChildEvents, &IID_IChildEvents, &LIBID_XXX> 
    { 
    public: 
        CChildEvents(void) : 
        m_pItfMgr(0) 
        { 
        } 
    
        /* called from internalQI to tear off a new blind interface */ 
        static HRESULT WINAPI _BlindQuery(void *pvThis, REFIID riid, void **ppv, DWORD dw); 
    
        DECLARE_REGISTRY_RESOURCEID(IDR_CHILDEVENTS) 
        DECLARE_PROTECT_FINAL_CONSTRUCT() 
    
        BEGIN_COM_MAP(CChildEvents) 
         COM_INTERFACE_ENTRY(IChildEvents) 
         COM_INTERFACE_ENTRY(IDispatch) 
         COM_INTERFACE_ENTRY_FUNC_BLIND(0, _BlindQuery) 
        END_COM_MAP() 
    }; 
    
    
    HRESULT WINAPI CChildEvents::_BlindQuery(void *pvThis, REFIID riid, void **ppv, DWORD /* dw */) 
    { 
        HRESULT hr = E_NOINTERFACE; 
        USES_CONVERSION; 
    
        try 
        { 
         if(pvThis == NULL) 
         { 
          ATLASSERT(FALSE); 
         } 
         else 
         { 
          /* 
          * cast the pvThis pointer to the actual class £ 
          * so we can use it here £ 
          * reinterpret_cast should be safe since we're calling ourself 
          */ 
          CChildEvents *pThis = reinterpret_cast < CChildEvents * > (pvThis); 
          if(pThis == NULL) 
          { 
           ATLASSERT(FALSE); 
          } 
          else 
          { 
    
            /* check to see if it matches on of our children's DIID */ 
                if(memcmp(&riid,&l_someotherguid,sizeof(GUID)) == 0) { 
    
             /* if so cast to a IDispatch -- the standard for event interfaces */ 
             *ppv = reinterpret_cast < IDispatch * > (pvThis); 
    
             /* addref */ 
             pThis->AddRef(); 
    
             /* reply */ 
             hr = S_OK; 
    
           } 
          } 
         } 
        } 
        catch(...) 
        { 
         ATLASSERT(FALSE); 
        } 
    
        /* must not be in our map - tell them to GO FISH */ 
        return(hr); 
    } 
    
    +0

    아니요, 저는 없습니다. 모든 합리적인 설정으로 마법사를 시도했지만 그러한 함수를 선언하지는 않습니다. 나도이 이름으로 인터넷 검색을했다. 네가 이름의 철자가 틀렸습니까? – sharptooth

    +0

    나는 낡은 코드를 파헤 치고 블라인드 쿼리가 실제로 내 자신의 함수라는 것을 알았다. LOL ..이 매크로를 사용하십시오 http://msdn.microsoft.com/en-us/library/5b6w5bwx(VS.80).aspx –

    +0

    글쎄, 이것은 QI()에 연결하는 좋은 방법입니다.하지만 그게 전부입니다. IMarshal이 포함 된 iterfaces 집합에 함수가 호출되었습니다. 명백한 이유가 없습니다. – sharptooth

    5

    에서 COM 런타임 (합니다 oleautomation) 마샬링 당신은 그것의 CLSID {00020424-0000-0000-C000-000000000046}을 추가하여 표준 마샬 러를 사용하여 같은 인터페이스를 표시하는 경우 형식 라이브러리를 사용합니다 HKCR\Interfaces\{iid}\ProxyStubClsid 아래에 있습니다. 여기서 {iid}는 사용자 인터페이스의 GUID입니다. 런타임에 매개 변수 정보를 추출하려면 형식 라이브러리가 등록되어 있어야하며 유형의 특정 하위 집합 만 사용할 수 있습니다. 좀 더 (오래된) 정보 herehere이 있습니다.

    IDL에서 MIDL 컴파일러에 의해 생성 된 사용자 지정 프록시/스텁을 사용하려는 경우 대신 인터페이스 레지스트리 항목을 해당 프록시 개체의 CLSID로 변경해야합니다. 이렇게하면 더 넓은 범위의 유형을 사용할 수 있습니다 (예 : "원시"배열.

    IMarshal을 지원하는 경우 이러한 메커니즘보다 우선적으로 사용됩니다. 즉, 레지스트리에서 아무 것도 변경하지 않고도 무료 스레드 마샬 러 (IMarshal 구현 사용)를 집계하도록 개체를 변경할 수 있습니다. 이렇게하면 프록시가 생성되지 않습니다.

    희망이 도움이됩니다.

    +0

    하지만 이상한 동작, 특히 IMarshal에 대한 런타임 구성 요소 QIs 및 E_NOINTERFACE를 얻을 때 HKCR \ Interface \ {InterfaceId} 키를 조회하지 않으려 고하는 이유는 무엇입니까? – sharptooth

    +0

    여기에서 문서를 보았습니까 http://msdn.microsoft.com/en-us/library/ms678428%28VS.85%29.aspx? 어쩌면 당신은 CoMarshalInterface (궁극적으로 COM 런타임이 수행하는 것입니다)를 호출하는 작은 테스트 케이스를 구성 할 수 있고, 어떤 일이 발생하는지 추적 할 수 있습니다. 나는 그것을 시험해 보았고 regmon을 가지고 레지스트리를 때리는 것을 볼 수 있었다. – voyce

    관련 문제