我必须在CComPtr对象上调用Release()方法吗? [英] Do I have to call Release() method on CComPtr objects?

查看:182
本文介绍了我必须在CComPtr对象上调用Release()方法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用SAPI5 API处理文本到语音.如果我简化了代码,则如下所示(我删除了错误检查以尽可能简化代码):

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

出于某些奇怪的原因,如果我不调用spVoice.Release(),我的代码将崩溃.因此,上面的代码崩溃了,但是这段代码很好地工作了:

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

CComPtr不会在超出范围时自动释放基础对象吗?

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

我查看了CComPtr的实现,它确实在析构函数本身中调用Release.

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

所以我想知道可能出了什么问题,为什么如果我自己调用Release,我的代码不会崩溃.但是,如果我不打电话给Release,它将崩溃.

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.

推荐答案

CComPtr的析构函数将调用Release.但是,当对象超出范围时,它会执行此操作.在上面的代码中,这恰好在main返回之前,即在对CoUninitialize的调用之后 .

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.

以下代码更正确,并确保析构函数在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;
}

另一种方法是围绕CoInitialize/CoUninitialize创建RAII包装器.如果在spVoice之前声明了这个新对象,则其析构函数将在spVoice的析构函数之后运行,以确保顺序正确.

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.

这篇关于我必须在CComPtr对象上调用Release()方法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆