自己写了个DLL连接数据库.当调用这个DLL的EXE退出的时候,就出现Crash.Crash的地方是:
//c:\program files\microsoft visual studio 8\vc\include\comip.h
void _Release() throw()
{
if (m_pInterface != NULL) {
m_pInterface->Release(); //Crash
}
}如果我把DLL中的代码放在Application中,即不用DLL,就没有问题.我现在分离出了最小的代码集.可能还是有点长.
DLL的入口是一个CDataCenter类,它的静态方法调用一个实现了单态模式的类CADOManager,CADOManager类中包含一个成员变量_ConnectionPtr m_pCon;连接和关闭数据库就是调用m_pCon的方法.///////////////DataAccess.DLL//class CADOManager
//ADOManager.h
class CADOManager
{
friend CADOManager* TheADOManager();
public:
CADOManager(void);
public:
~CADOManager(void);
BOOL Inital();
BOOL ExInital();
private:
_ConnectionPtr m_pCon;
static auto_ptr<CADOManager> m_instance;
};
CADOManager* TheADOManager();
//ADOManager.cpp
auto_ptr<CADOManager> CADOManager::m_instance;
CADOManager::CADOManager(void)
{
}CADOManager::~CADOManager(void)
{
}BOOL CADOManager::Inital()
{
m_pCon.CreateInstance(__uuidof(Connection));
m_pCon->Open(_bstr_t(_T("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\\sss.xls;Extended Properties=\"Excel 8.0;HDR=Yes\";")),_bstr_t(_T("")),_bstr_t(_T("")),adModeUnknown);
return TRUE;
}
BOOL CADOManager::ExInital()
{
m_pCon->Close();
return TRUE;
}
CADOManager* TheADOManager()
{
if(0 == CADOManager::m_instance.get())
{
CADOManager::m_instance.reset(new CADOManager);
}
return CADOManager::m_instance.get();
}//class CDataCenter
//DataCenter.h
class __declspec(dllexport) CDataCenter
{
public:
static BOOL Inital();
static BOOL ExInital();
};//DataCenter.cpp
BOOL CDataCenter::Inital()
{
TheADOManager()->Inital();
return TRUE;
}
BOOL CDataCenter::ExInital()
{
TheADOManager()->ExInital();
return TRUE;
}////////////////////////Appliaction
//Code:
CDataCenter::Inital();
CDataCenter::ExInital();
//c:\program files\microsoft visual studio 8\vc\include\comip.h
void _Release() throw()
{
if (m_pInterface != NULL) {
m_pInterface->Release(); //Crash
}
}如果我把DLL中的代码放在Application中,即不用DLL,就没有问题.我现在分离出了最小的代码集.可能还是有点长.
DLL的入口是一个CDataCenter类,它的静态方法调用一个实现了单态模式的类CADOManager,CADOManager类中包含一个成员变量_ConnectionPtr m_pCon;连接和关闭数据库就是调用m_pCon的方法.///////////////DataAccess.DLL//class CADOManager
//ADOManager.h
class CADOManager
{
friend CADOManager* TheADOManager();
public:
CADOManager(void);
public:
~CADOManager(void);
BOOL Inital();
BOOL ExInital();
private:
_ConnectionPtr m_pCon;
static auto_ptr<CADOManager> m_instance;
};
CADOManager* TheADOManager();
//ADOManager.cpp
auto_ptr<CADOManager> CADOManager::m_instance;
CADOManager::CADOManager(void)
{
}CADOManager::~CADOManager(void)
{
}BOOL CADOManager::Inital()
{
m_pCon.CreateInstance(__uuidof(Connection));
m_pCon->Open(_bstr_t(_T("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\\sss.xls;Extended Properties=\"Excel 8.0;HDR=Yes\";")),_bstr_t(_T("")),_bstr_t(_T("")),adModeUnknown);
return TRUE;
}
BOOL CADOManager::ExInital()
{
m_pCon->Close();
return TRUE;
}
CADOManager* TheADOManager()
{
if(0 == CADOManager::m_instance.get())
{
CADOManager::m_instance.reset(new CADOManager);
}
return CADOManager::m_instance.get();
}//class CDataCenter
//DataCenter.h
class __declspec(dllexport) CDataCenter
{
public:
static BOOL Inital();
static BOOL ExInital();
};//DataCenter.cpp
BOOL CDataCenter::Inital()
{
TheADOManager()->Inital();
return TRUE;
}
BOOL CDataCenter::ExInital()
{
TheADOManager()->ExInital();
return TRUE;
}////////////////////////Appliaction
//Code:
CDataCenter::Inital();
CDataCenter::ExInital();
解决方案 »
- 关于 vc2008 GetMenu()->GetSubMenu(2)->CheckMenuItem 问题
- VC中WebBrowser控件应用的问题
- 关于CRect
- 判断一下这个结构定义的大小^=^
- vc多线程中new的指针在另一个线程中如何正确释放?
- 请教:怎样把一个动画gif切分为多个动画gif?
- 我的程序中数据全是double型的,我想优化它,该如何着手,请各位指教。
- U盘 实时监控
- 问:<<windows程序设计>>是哪个出版社出版的?how money?有39分
- 新手求助:VC++编写excel dll问题
- 怎么编程实现取出ACCESS数据表的主键
- 关于CEDIT的VSCROLL自动滚动的问题!
try
{
...
}
catch(_com_error e)
{
printf("%s\n", (char*)e.Description());
return;
}
把错误抛出来看看。
是不是可以捕获所有的exception,包括com的
那用什么???
这个世道还有什么千万别用.
是不是千万别用goto啊.
不是千万别用,是自己不会用.
虽然catch(...)会抓住所有异常,但你就不能在这之前抓你知道的异常吗??
智能指针是双刃剑,可用剑的是人.剑本身是不会伤人的.
因为一个东西有可能造成危害就不使用???
因噎废食.
虽然catch(...)会抓住所有异常,但你就不能在这之前抓你知道的异常吗??
我的意思是在catch(...)语句前用其他catch语句.
John Robbins说的就是对的???如果catch(...)是万恶之源为什么现在还没把它从C++里面去除???根据需要使用就是对的.人才是万恶之源.
catch(...)的目的就是让你抓住未知和未捕捉的异常.
如何使用是你自己的问题和catch(...)有什么关系???
有时候抓住异常并不是要处理异常本身,而是让程序正常的退出.或者让程序继续运行.
程序异常中止的对话框对程序员和调试人员也许有用.但对用户来说.没有任何作用.程序员写的程序是给用户用的,不是自己用的.
Access Violation, Heap Corruption, int 3,除0
这些错误对局部是致命的.但如果这只是程序一个不重要的环节或者可以恢复的环节.那你也要中止程序???
我认为程序应该最大可能的从错误中恢复而不是有错误就挂掉.想法不一样.没必要再说下去了.
我目前的程序,就需要catch(...) 因为我也不知道哪里异常了,但是程序要发布给用户,总不能让程序老崩溃,所以就catch(...)。然后自己慢慢找bug,等找到了,再加catch(xxx e)
从中确实学到了很多知识.
我在BOOL CADOManager::ExInital()中增加了一行代码:m_pCon->Release().只要外部程序在退出之前调用了CADOManager::ExInital(),就会释放掉智能指针m_pCon.
BOOL CADOManager::ExInital()
{
m_pCon->Close();
m_pCon->Release(); //显示调用释放函数,避免在CoUninitialize之后释放.
return TRUE;
}