1

将我的 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() 为两个线程返回相同的内容。这就是我陷入困境的地方 - 我不知道是什么导致了这种行为......

4

1 回答 1

2

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

于 2012-04-18T11:26:15.180 回答