I have been trying to do a basic ActiveX component marshalling for across thread access. I do it through a Global Interface Table (GIT) . I have a simple MFC dialog to which I add an arbitrary AciveX control such as IDC_PDF. Inserting activeX control to MFC dialog in C++
After that I add the variable representing this control to the code. This effectively adds a pdf1.h and pdf1.cpp to the project. At initialization of the dialog inside OnInitDialog() I try to marshal the interface to this ActiveX component so that it could be used from another thread without STA apartment violation.
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;
}
As a result the value of the dwCookie is set to 256, which though not 0, still feels like an error value. When I try to get the marshalled interface from another thread. The marshalled interface received is 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;
}
What am I doing wrong? I am working with a standard ActiveX, using standard marshalling patern. Anybody got this to work?
RegisterInterfaceInGlobal()
andGetInterfaceFromGlobal()
require an Interface ID (IID). However,Pd_OCX_fControl.GetClsid()
looks like a function to retrieve the class ID (CLSID). – AuroraInvokeHelper()
callls inside. How can I use it to help me execute methods on the marshaled interface? It can't be true that no one has not tried to marshal some third party ActiveX controls?!! – user3070144