bodacydo
bodacydo

Reputation: 79379

Do I have to call Release() method on CComPtr objects?

I'm working with SAPI5 API for processing text to speech. If I simplify my code looks like this (I removed error checking to simplify it as much as possible):

int main() {
    CoInitialize(NULL);
    CComPtr<ISpVoice> spVoice;
    spVoice.CoCreateInstance(CLSID_SpVoice);
    ...
    CoUninitialize();
    return 0;
}

For some weird reason my code crashes if I don't call spVoice.Release(). So the code above crashes, but this code works nicely:

int main() {
    CoInitialize(NULL);
    CComPtr<ISpVoice> spVoice;
    spVoice.CoCreateInstance(CLSID_SpVoice);
    ...
    spVoice.Release();
    CoUninitialize();
    return 0;
}

Doesn't CComPtr release the underlying object automatically as it goes out of scope?

I looked at the implementation of CComPtr and it does call Release in the destructor itself.

So I'm wondering what could have gone wrong and why is it that if I call Release myself, my code doesn't crash. But if I don't call Release then it crashes.

Upvotes: 3

Views: 7352

Answers (2)

Michael
Michael

Reputation: 55415

CComPtr's destructor will call Release. However, it does that when the object falls out of scope. In your above code, this is just before main returns, which is after the call to CoUninitialize.

The following code is more correct, and guarantees the destructor runs prior to CoUninitialize.

int main() {
    CoInitialize(NULL);
    { // Begin scope
        CComPtr<ISpVoice> spVoice;
        spVoice.CoCreateInstance(CLSID_SpVoice);
        ...
    } / End scope, spVoice's destructor runs.
    CoUninitialize();
    return 0;
}

An alternative is to create an RAII wrapper around CoInitialize/CoUninitialize. If this new object is declared prior to spVoice, it's destructor will run after spVoice's destructor, guaranteeing correct order.

Upvotes: 11

mox
mox

Reputation: 6314

You are right, you must NOT invoke Release. This is done automatically in the destructor. One reason of the crash might be a side effect that takes place because you don't initialize the COM appartment at the begin of your program.

Upvotes: -1

Related Questions