使用Com组件的时候,注意接口的释放

创建一个atl的exe组件,增加了一个从IUnknown派生的接口,当在客户端创建这个接口成功后,在退出的时候调用Release程序出现如下的错误,Cannot execute program .这是问什么?
 
   产生上述错误的原因:
    在客户端的程序是一个基于对话框的程序,在该程序的C**APP:: InitInstance()函数的开头和结尾增加了如下代码,已实现调用Com接口.
       BOOL CMy****App::InitInstance()
{
 AfxEnableControlContainer();
    CoInitialize(NULL);
 // Standard initialization
 // If you are not using these features and wish to reduce the size
 //  of your final executable, you should remove from the following
 //  the specific initialization routines you do not need.

#ifdef _AFXDLL
 Enable3dControls();   // Call this when using MFC in a shared DLL
#else
 Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif

 CMyFinalCliDlg dlg;
 m_pMainWnd = &dlg;
 int nResponse = dlg.DoModal();
 if (nResponse == IDOK)
 {
 }
 else if (nResponse == IDCANCEL)
 {
  // TODO: Place code here to handle when the dialog is
  //  dismissed with Cancel
 }
CoUninitialize();
 return FALSE;
}

在程序退出的时候,当执行完CoUninitialize()后CMy****Dlg的析购函数才备调用,在析构函数中,调用Release去释放接口的时候,由于Com环境都已经释放了,还掉用Release就导致了上述的错误结果。
改正方法:
在CMy****Dlg的构造函数中加:CoInitialize(NULL);在CMy****Dlg的析构函数中在Releaae后接口后,调用CoUninitialize();就可以避免该错误.

注意:
? 如果从IDispatch接口派生,那么在CMy****App的InitInstance函数中释放Com环境却不会出错。很奇怪.
? 如果通过导入tlb库的话,那么应该这样申明:
1. 通过CLSID 和IID创建接口
#include "Server_i.c"                  //定义CLS_ID和IID
#import "Server.tlb" rename_namespace("ServerDriver")
using namespace ServerDriver;
ITest2* m_pComm;        
…..
HRESULT hr = S_OK;
 hr = CoCreateInstance(CLSID_Test2,NULL,CLSCTX_LOCAL_SERVER,IID_ITest2,reinterpret_cast<void**>(&m_pComm));
 if(SUCCEEDED(hr))
 {
}
2. 通过__uuidof创建接口
如果不调用:#include "Server_i.c",那么创建接口只能通过如下方式:
ITest2Ptr  m_pComm;    //……2……

 HRESULT hr = S_OK;
 hr = m_pComm.CreateInstance(__uuidof(Test2));
 if(SUCCEEDED(hr))
 {
}

注意: 使用两种方法中申明对象的不同,当导入库的时候,会在客户端的Debug文件夹中生成:***.tlh的文件。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值