VC++,COM析构时间
来源:互联网 发布:淘宝技术论坛 编辑:程序博客网 时间:2024/06/10 15:29
针对解决的问题:
调用COM+,能够得到想要的结果,在执行最后return 0这句之后就报错。
报错位置在 comip.h
void _Release() throw()
{
if (m_pInterface != NULL) {
m_pInterface->Release(); // 在这里报的错
}
void _Release() throw()
{
if (m_pInterface != NULL) {
m_pInterface->Release(); // 在这里报的错
}
}
COM析构时间:(引自http://blogs.msdn.com/b/oldnewthing/archive/2004/05/20/135841.aspx)
Larry Osterman discussed the importance of knowing when your global destructors run, but this problem is not exclusive to global objects. You need to take care even with local objects. Consider:
void Sample(){ if (SUCCEEDED(CoInitialize(NULL))) { CComPtr<IXMLDOMDocument> p; if (SUCCEEDED(p.CoCreateInstance(CLSID_IXMLDOMDocument))) { ... } CoUninitialize(); }}
Easy as pie. And there's a bug here.
When does the destructor for that smart-pointer run?
Answer: When the object goes out of scope, which is at the closing brace of the outer if
statement, after the CoUninitialize
call.
So you shut down COM, and then try to access a pointer to a COM object. This is not good. (Or as Larry describes it, "Blam!")
To fix this problem, you have to release all your COM pointers before the CoUninitialize
. One way would be to insert a p.Release()
at the end of the inner if
. (But of course, if you're going to do that, then why bother using a smart pointer?)
Another fix would be to introduce a seemingly unnecessary scope:
void Sample(){ if (SUCCEEDED(CoInitialize(NULL))) { { CComPtr<IXMLDOMDocument> p; if (SUCCEEDED(p.CoCreateInstance(CLSID_IXMLDOMDocument))) { ... } } // ensure p is destructed before the CoUninit CoUninitialize(); }}
Make sure you leave that comment there or the next person to come across this code is going to "clean it up" by removing the "redundant" braces.
Of course, this is still too subtle. Here's another solution: Put the CoUninitialize inside a destructor of its own!
class CCoInitialize {public: CCoInitialize() : m_hr(CoInitialize(NULL)) { } ~CCoInitialize() { if (SUCCEEDED(m_hr)) CoUninitialize(); } operator HRESULT() const { return m_hr; } HRESULT m_hr;};void Sample(){ CCoInitialize init; if (SUCCEEDED(init)) { CComPtr<IXMLDOMDocument> p; if (SUCCEEDED(p.CoCreateInstance(CLSID_IXMLDOMDocument))) { ... } }} // CoUninitialize happens here
This works even if you put the smart pointer at the same scope, as long as you put it after the CCoInitialize object:
void Sample(){ CCoInitialize init; CComPtr<IXMLDOMDocument> p; if (SUCCEEDED(init) && SUCCEEDED(p.CoCreateInstance(CLSID_IXMLDOMDocument))) { ... }}
This works because objects with automatic storage duration are destructed in reverse order of declaration, so the object p
wil be destructed first, then the object init
.
Mind you, this is basically subtle no matter now you slice it. Nobody said programming was easy.
- VC++,COM析构时间
- [vc] com
- VC++ COM
- VC----COM
- VC时间
- VC时间
- VC进行COM编程
- vc com理论知识
- VC调用COM组件
- vc 如何调用com
- VC调试COM对象
- VC COM接口编程
- VC Com调用
- vc 使用COM
- vc 如何调用com
- VC调用COM组件
- vc++ 操作COM
- vc++导入com组件
- 关于跨域访问
- 关于IIS报的确进程在与 World Wide Web Publishing 服务通信时遇到致命错误。进程 ID 为 '4528'。数据字段包含错误号 的解决办法
- Modem的调试以及AT命令【转载】
- Oracle常用sql语句备忘录
- Linux网络编程必看书籍推荐
- VC++,COM析构时间
- 关于Java的23种设计模式的有趣见解
- packageInfo相关类应用
- CEdit控件内回车换行方法
- mysql alter 语句用法,添加、修改、删除字段等
- 扁平疣治疗
- linux下ant的安装
- Display
- Jacob使用小结