创建一个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)); [Page] 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条评论)
登录后参与讨论