1

私の問題は、VS2003 プロジェクトを VS2008 に変換した後に始まりました。ソリューションには 3 つのプロジェクトが含まれています。プロジェクトは DLL です。たくさんのコンパイル エラーがあり、それからいくつかのリンカ エラーがありました...まあ、私はそれらを撃退しました。今は単に機能しません;)

したがって、この DLL の 1 つが 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ではなくCoInitializeExでCOINIT_MULTITHREADEDを指定してCOMを初期化する必要があります。そうしないと、スレッドごとに個別のシングルスレッド COM アパートメントが作成されます。

于 2012-04-18T11:26:15.180 に答える