2017-11-23 6 views
0

나는 스레드 액세스를 가로 질러 마샬링하는 기본 ActiveX 구성 요소를 수행하려고 시도 해왔다. GIT (Global Interface Table)를 통해이 작업을 수행합니다. IDC_PDF와 같은 임의의 AciveX 컨트롤을 추가하는 간단한 MFC 대화 상자가 있습니다. Inserting activeX control to MFC dialog in C++전역 인터페이스 테이블을 통해 ActiveX를 마샬링

그 다음이 컨트롤을 나타내는 변수를 코드에 추가합니다. 이렇게하면 pdf1.hpdf1.cpp이 프로젝트에 효과적으로 추가됩니다. 대화 상자 초기화시 OnInitDialog() STA 아파트 위반없이 다른 스레드에서 사용할 수 있도록이 ActiveX 구성 요소에 대한 인터페이스를 마샬링하려고합니다. 0하지 않지만, 여전히 에러 값과 같은 느낌 dwCookie의 값은 256로 설정된다 그 결과,

bool CLMC_mfcDlg::CreateMarshalledController() 
{ 

    ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); 
    CComPtr<IGlobalInterfaceTable> pGIT; 

    // get pointer to GIT 
    CoCreateInstance(CLSID_StdGlobalInterfaceTable, 
     NULL, 
     CLSCTX_INPROC_SERVER, 
     IID_IGlobalInterfaceTable, 
     (void **)&pGIT); 

    // get IID and IUnknown interface pointer 
    REFIID iid = Pd_OCX_fControl.GetClsid(); 
    IUnknown* active_x_pointer = Pd_OCX_fControl.GetControlUnknown(); 

    // register interface inside the GIT 
    if (active_x_pointer != NULL) { 
     HRESULT hr = pGIT->RegisterInterfaceInGlobal(active_x_pointer, iid, &dwCookie); 
     if (SUCCEEDED(hr)) 
     { 
      // OK, wir haben das interface im GIT registriert 
      assert(dwCookie != 0); 
     } 
     else 
      dwCookie = 0; 

     //pGIT->Release(); 
    } 
    else 
     dwCookie = 0; 
    active_x_pointer->Release(); 
    return dwCookie!=0; 
} 

. 다른 스레드에서 마샬링 된 인터페이스를 가져 오려고 할 때. 수신 된 정렬 화 된 인터페이스는 0x0000입니다.

bool CLMC_mfcDlg::FetchMarshalledController() 
{ 
    HRESULT res = ::OleInitialize(NULL); 

    switch (res) 
    { 
    case S_OK: 
     break; 
    case OLE_E_WRONGCOMPOBJ: 
    case RPC_E_CHANGED_MODE: 
     return false; 
    } 
    CComPtr<IGlobalInterfaceTable> pThreadGIT; 
    CoCreateInstance(CLSID_StdGlobalInterfaceTable, 
     NULL, 
     CLSCTX_INPROC_SERVER, 
     IID_IGlobalInterfaceTable, 
     (void **)&pThreadGIT); 
    REFIID iid = Pd_OCX_fControl.GetClsid(); 
    pThreadGIT->GetInterfaceFromGlobal(
     dwCookie, iid, (void**)&pMarshalledOCX); 


    pThreadGIT->RevokeInterfaceFromGlobal(dwCookie); 
    return pMarshalledOCX != nullptr; 
} 

내가 뭘 잘못하고 있니? 나는 standard marshalling patern을 사용하는 표준 ActiveX로 작업하고있다. 아무도이 일을 할 수 있니?

+0

'RegisterInterfaceInGlobal()'와'GetInterfaceFromGlobal()'인타 ID (IID)를 필요로한다. 그러나'Pd_OCX_fControl.GetClsid()'는 클래스 ID (CLSID)를 검색하는 함수처럼 보입니다. – Aurora

+0

256이 정상입니다. 실제로 인터페이스를 마샬링하는 것은 도움이되는 구성 요소를 필요로합니다. COM에게 이것이 어떻게 수행되어야하는지 알려주는 레지스트리 키를 생성해야합니다. 인터페이스의 IID로 명명 된 HKLM \ Software \ Wow6432Node \ Classes \ Interface 키의 하위 키입니다. ActiveX 컨트롤은 거의 사용하지 않으며 UI 스레드에서만 사용 가능하고 실제로 사용되기를 기대합니다. 이러한 호출의 반환 값을 무시하지 말고 실패한 이유를 알려줍니다. –

+0

고마워요, Aurora, Hans. 실제 GIT 테이블 (GetInterfaceFromGlobal)에서 마샬링 된 인터페이스를 호출하면 E_UNEXPECTED 치명적인 오류가 반환됩니다. 오로라, CLSID와 REFIID가 실제로 동일하다는 것을 읽었습니다. 그러나 당신은 옳은 것처럼 보입니다. 시스템에 설치된 표준 ActiveX에서 REFIID 또는 GUID를 얻으려면 어떻게합니까? – user3070144

답변

0

오로라가 정확했습니다. 당신은 인터페이스 포인터를 얻을

static REFIID const intf_id 
     = { 0x5CD5C9C3, 0x0CD7, 0x453A,{ 0x8D, 0x27, 0xE3, 0xBB, 0x32, 0xB7, 0xEA, 0xFC } }; 

: oleview.exe

이 코드에서 인터페이스의 IID를 정의하는 발견을 사용 : 적절한 IID를 얻으려면 사용하여 레지스트리에서 인터페이스 oleview.exe을 찾을 필요 이를 위해 :

IUnknown * pUnknown = CBaldorOCXCard.GetControlUnknown(); 
// get _DMintControllerCtrl interface pointer 
void* IMint = NULL; 
pUnknown->QueryInterface(intf_id, (void **)&IMint); 

마샬링에 인터페이스 포인터와 IID를 사용할 수 있습니다.

(당신이 래퍼 클래스없이이 인터페이스 포인터를 작동하는 방법 : 아직 답을 찾고 문제)

관련 문제