开发环境:VC7.1
我用VC7.1+ATL做了一个COM,很简单,就是取本地计算机的域名。在调试它的时候,我发现一个奇怪的事。
我用MFC做了一个程序来测试这个COM,结果我发现按照手头找到的资料不能正确的编码。大家请看下面的调用代码:
void CMFCTestDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
HRESULT hr = CoInitialize(NULL);
IDNSInfoPtr ptrDNSInfo(__uuidof(CDNSInfo)); BSTR bstrDomainName;
ptrDNSInfo->get_DomainName(&bstrDomainName);
CString cstrDomainName(bstrDomainName);
SetDlgItemText(IDC_STATIC, cstrDomainName.GetString());
/*请注意下面这行,在我找到的所有资料中,都没有下面这一行,但如果我不把这个指针置空,执行CoUninitialize()时就会出错,提示不能Release。以我对C++的粗浅了解,这样把一个指针置空似乎有内存泄漏的危险?无论如何,现在程序是可以运行了,不过还是欢迎大家一起来讨论一下这个现象的原因。*/
ptrDNSInfo = NULL;
CoUninitialize();
}
我用VC7.1+ATL做了一个COM,很简单,就是取本地计算机的域名。在调试它的时候,我发现一个奇怪的事。
我用MFC做了一个程序来测试这个COM,结果我发现按照手头找到的资料不能正确的编码。大家请看下面的调用代码:
void CMFCTestDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
HRESULT hr = CoInitialize(NULL);
IDNSInfoPtr ptrDNSInfo(__uuidof(CDNSInfo)); BSTR bstrDomainName;
ptrDNSInfo->get_DomainName(&bstrDomainName);
CString cstrDomainName(bstrDomainName);
SetDlgItemText(IDC_STATIC, cstrDomainName.GetString());
/*请注意下面这行,在我找到的所有资料中,都没有下面这一行,但如果我不把这个指针置空,执行CoUninitialize()时就会出错,提示不能Release。以我对C++的粗浅了解,这样把一个指针置空似乎有内存泄漏的危险?无论如何,现在程序是可以运行了,不过还是欢迎大家一起来讨论一下这个现象的原因。*/
ptrDNSInfo = NULL;
CoUninitialize();
}
解决方案 »
- ado获取记录集,弹出错误“多步操作产生错误。请检查每一步的状态值。”
- 向各位大哥请求group by算法
- 程序主对话框怎么设置角上的图标啊
- 用socket下载文件问题,下载不成功!
- 无法解决的问题,AfxBeginThread产生异常?
- VC制作的COM组件,编译成DLL后,怎样生成CAB文件,放到网页中<OBJECT>里面,就可以自动下载?
- 我从网上下的.icl的图标,可打不开,怎么用啊?
- 如何使SHBrowseForFolder只能选择本地目录,不能选择网络路径
- 关于鱼鱼桌面秀的实现原理
- 程序开了上万个端口监听,有的电脑上可以,有的电脑上大批量的监听失败。
- 我想学习com/Dcom技术,请各位推荐一下用什么书入门和提高~~~
- 我的DLL中调用GetPrivateProfileString取不到数据,为什么?
ptrDNSInfo是智能指针,出作用域会自动析构,所以如果不手工释放,ptrDNSInfo将在CoUninitialize();之后释放,但是CoUninitialize();之后COM对象已经不存在了,所以再释放ptrDNSInfo就不对了,这和是不是用vc7.1没有关系。
试过Release,还是会非法操作,还有,这是指针,应该用->操作符吧
我本来是想把CoInitialize放在构造里,把CoUninitialize放在析构里……MFC里没有自动生成析构,我就懒得写了……
良心谴责一下自己……
应该用->操作符吧
用. 正确,可以看看他的源码,
用. 可以在 ptrDNSInfo.p==NULL的时候调用
HRESULT hr = CoInitialize(NULL);
{
IDNSInfoPtr ptrDNSInfo(__uuidof(CDNSInfo)); BSTR bstrDomainName;
ptrDNSInfo->get_DomainName(&bstrDomainName);
CString cstrDomainName(bstrDomainName);
SetDlgItemText(IDC_STATIC, cstrDomainName.GetString());
}CoUninitialize();
还有一个问题就是,如果我在类中定义一个智能指针成员变量,在构造中给它分配了资源,还需要在析构中释放它吗?它在类析构时会不会自动释放自己呢?
CoInitialize()在每个用到COM的线程中都要调用。SDK文档要求每一次成功的CoInitialize调用也要有相对应显式的调用CoUninitialize。不一定要在析构中
你可以在ExitInstance()中 explicitly release smart pointer.也就是 设m_pXXX=NULL;
或者,偷懒的办法:
class Base
{
public:
Base()
{
CoInitialize(NULL);
}
~Base()
{
CoUninitialize();
}
};
class Sub:private Base
{
//your smart point member here
...
};
因为base class的constructor在sub之前调用,destructor在sub之后调用,这样你不用手工release sub的smart point members
Onega() 的办法好
看来今天要准备结贴了,不然区区三百分儿拿出来分有些对不起各位高手:)
CoInitialize是初始化com库,CoUninitialize释放com库的资源。
还有实质不需要置空,只需要ptrDNSInfo.Release()之后CoUnitialize()就完事大吉。
Analyst() is correct, the problem is that the object is released/destroyed when it goes out of the scope, but at that time, your CoUninitialize() is already called, so you got an error, try to put the code inside { ....} or in try/catch block
HRESULT hr = CoInitialize(NULL);
{
IDNSInfoPtr ptrDNSInfo(__uuidof(CDNSInfo)); BSTR bstrDomainName;
ptrDNSInfo->get_DomainName(&bstrDomainName);
CString cstrDomainName(bstrDomainName);
SetDlgItemText(IDC_STATIC, cstrDomainName.GetString());
}CoUninitialize();