通过全局接口编组 ActiveX Table

Marshalling ActiveX through Global Interface Table

我一直在尝试为跨线程访问进行基本的 ActiveX 组件编组。我通过全局接口 Table (GIT) 来完成。我有一个简单的 MFC 对话框,我向其中添加了任意 AciveX 控件,例如 IDC_PDF。 Inserting activeX control to MFC dialog in C++

之后,我将表示此控件的变量添加到代码中。这有效地向项目添加了 pdf1.hpdf1.cpp。在初始化 OnInitDialog() 中的对话框时,我尝试将接口编组到此 ActiveX 组件,以便可以从另一个线程使用它而不会违反 STA 单元。

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;
}

因此 dwCookie 的值被设置为 256,虽然不是 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;
}

我做错了什么?我正在使用标准的 ActiveX,使用标准的编组模式。有人让这个工作吗?

Aurora 是正确的。要获得正确的 IID,您需要使用 oleview.exe 在注册表中找到接口:

您使用该发现在您的代码中定义接口 IID:

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

你得到它的接口指针是这样的:

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

现在可以在编组中使用接口指针和 IID。

(关于如何在没有包装器的情况下使用此接口指针的问题 class:)仍在寻找答案)