为什么COM不能在新线程中工作?

时间:2012-04-18 11:19:49

标签: c++ windows com

将我的VS2003项目转换为VS2008后,我的问题就出现了。解决方案包含3个项目项目是DLL的。有很多编译错误,然后是一些链接器错误......好吧,我打了他们。现在它只是不起作用;)

因此,其中一个DLL被允许通过COM与Word通信。

Word::_ApplicationPtr d_pApp;
Word::_DocumentPtr d_pDoc;

void MSWord2003::init()
{
    free();
    HRESULT hr;
    CLSID clsid;
    CLSIDFromProgID(L"Word.Application", &clsid);  

     // Get an interface to the running instance, if any..
    IUnknown *pUnk;

    hr = GetActiveObject(clsid, NULL, (IUnknown**)&pUnk);
    if(hr!=S_OK)
        throw MSWord::MSWordException("Nie znaleziono działającej aplikacji MSWord.");

    IDispatch* d_pDispApp;
    hr = pUnk->QueryInterface(IID_IDispatch, (void**)&d_pDispApp);
    if(hr!=S_OK)
        throw MSWord::MSWordException("Nie udało się połączyć z aplikacją MSWord.");

    pUnk->Release();
    pUnk = 0;

    d_pApp = d_pDispApp;
    d_pDoc = d_pApp->ActiveDocument;

    d_pDispApp->AddRef();   


    d_currIdx = -1;

    paragraphsCount = d_pDoc->GetParagraphs()->Count;
    footnotesCount = d_pDoc->GetFootnotes()->Count;
    endnotesCount = d_pDoc->GetEndnotes()->Count;
}

void MSWord2003::free()
{
    if(d_pApp!=0)
    {
        d_pApp->Release();
        d_pApp=0;
    }
}

此代码适用于VS2003(和不同的机器,我的计算机上没有VS2003),而在VS2008中它只有在主线程调用时才有效。 当由新线程调用(由CoInitialize初始化)时,d_pApp未正确初始化 - 其ptr显示为0.

调试时我在comip.h中找到了代码:

template<typename _InterfacePtr> HRESULT _QueryInterface(_InterfacePtr p) throw()
    {
        HRESULT hr;

        // Can't QI NULL
        //
        if (p != NULL) {
            // Query for this interface
            //
            Interface* pInterface;
            hr = p->QueryInterface(GetIID(), reinterpret_cast<void**>(&pInterface));

            // Save the interface without AddRef()ing.
            //
            Attach(SUCCEEDED(hr)? pInterface: NULL);
        }
        else {
            operator=(static_cast<Interface*>(NULL));
            hr = E_NOINTERFACE;
        }

        return hr;
    }

在一个新线程中,QueryInterface返回E_NOINTERFACE,尽管GetIID()为两个线程返回相同的内容。这就是我被卡住的地方 - 我不知道是什么导致了这种行为......

1 个答案:

答案 0 :(得分:2)

IMO你应该使用CoInitialize来初始化COM,但是使用CoInitializeEx,指定COINIT_MULTITHREADED。否则,每个线程都有单独的单线程COM公寓。