在程序中我把数据库操作部分封装成了一般的mfc扩展动态库,
在动态库中定义了一个全局变量:
_ConnectionPtr m_pConnection;
然后该动态库导出3个函数
1。初始化动态库
BOOL __declspec(dllexport) InitializeDbDll(CString mdbname)
{
m_pConnection.CreateInstance(_uuidof(Connection));
CString strConnect;
BSTR bstrSQL;
strConnect.Format("Provider = Microsoft.JET.OLEDB.4.0; Data Source=..\\bin\\%s",mdbname);
bstrSQL = strConnect.AllocSysString();
try
{
m_pConnection->Open(bstrSQL,"","",0); //连接mdbname数据库
}
catch (_com_error e)//异常处理
{
AfxMessageBox(e.ErrorMessage());
return false;
}
return true;
}
2.主程序退出时候清理动态库的连接智能指针
BOOL __declspec(dllexport) UnInitializeDbDll()
{
if (NULL!=m_pConnection) {
m_pConnection->Close();
}
return true;
}
3。执行一条sql语句,供主程序调用
BOOL __declspec(dllexport) ExecuteSQLEx(CString strSql)
{
_variant_t RecordsAffected;
_bstr_t bstrSql(strSql);
try
{
m_pConnection->Execute(bstrSql,&RecordsAffected,adCmdText);
}
catch (_com_error e)
{
AfxMessageBox(e.ErrorMessage());
// m_pConnection->Close();
return false;
}
return true;
}
在调试过程中,调用动态库中的执行sql语句函数运行正常,但是当主程序退出的时候报错,
如果我把上面的_ConnectionPtr m_pConnection;改为局部变量确不会报错。这让我感到非常困惑
,因为这样的话,我每次调用上面的ExecuteSQLEx执行sql语句时候都必须连接一次数据库,是的执行
效率下降。希望那位高手能指点一下。怎样在动态库中只连接一次数据库。(小弟在ado方面很菜鸟)顺便还想问问:用HANDLE fileHandle=CreateFile(..)创建的文件,为生么在关闭了文件的句柄fileHandle之后,其他程序仍然不能访问该文件。
在动态库中定义了一个全局变量:
_ConnectionPtr m_pConnection;
然后该动态库导出3个函数
1。初始化动态库
BOOL __declspec(dllexport) InitializeDbDll(CString mdbname)
{
m_pConnection.CreateInstance(_uuidof(Connection));
CString strConnect;
BSTR bstrSQL;
strConnect.Format("Provider = Microsoft.JET.OLEDB.4.0; Data Source=..\\bin\\%s",mdbname);
bstrSQL = strConnect.AllocSysString();
try
{
m_pConnection->Open(bstrSQL,"","",0); //连接mdbname数据库
}
catch (_com_error e)//异常处理
{
AfxMessageBox(e.ErrorMessage());
return false;
}
return true;
}
2.主程序退出时候清理动态库的连接智能指针
BOOL __declspec(dllexport) UnInitializeDbDll()
{
if (NULL!=m_pConnection) {
m_pConnection->Close();
}
return true;
}
3。执行一条sql语句,供主程序调用
BOOL __declspec(dllexport) ExecuteSQLEx(CString strSql)
{
_variant_t RecordsAffected;
_bstr_t bstrSql(strSql);
try
{
m_pConnection->Execute(bstrSql,&RecordsAffected,adCmdText);
}
catch (_com_error e)
{
AfxMessageBox(e.ErrorMessage());
// m_pConnection->Close();
return false;
}
return true;
}
在调试过程中,调用动态库中的执行sql语句函数运行正常,但是当主程序退出的时候报错,
如果我把上面的_ConnectionPtr m_pConnection;改为局部变量确不会报错。这让我感到非常困惑
,因为这样的话,我每次调用上面的ExecuteSQLEx执行sql语句时候都必须连接一次数据库,是的执行
效率下降。希望那位高手能指点一下。怎样在动态库中只连接一次数据库。(小弟在ado方面很菜鸟)顺便还想问问:用HANDLE fileHandle=CreateFile(..)创建的文件,为生么在关闭了文件的句柄fileHandle之后,其他程序仍然不能访问该文件。
if (NULL!=m_pConnection) {
m_pConnection->Close();
m_pConnection.Release(); //加上这个看看
}
CoInitialize(NULL);
CoUninitialize();
不调用Release也不会出错呢?
还有:智能指针m_pConnection,何时调“.”何时调"->"二者有什么不同。
还请指点一二。
--------------------------------------------------------------
.是调用他自己的方法。
-〉是调用他包装的指针的方法。提点意见;
1。搂主没有考虑InitializeDbDll被调用两次的情况。
2。在UnInitializeDbDll没有考虑数据连接失败的情况。
---------------------------------------------
好像和主动调用release没有关系呢。搂主可以调试一下。
是一个智能指针,里面封装了ADODB::Connection的接口指针
调用->Release()用于com的计数递减
调用.Release()除了包含->Release的功能,同时把里面封装的接口指针=NULL
在_ConnectionPtr m_pConnection;智能指针的析构函数里面会自动去判断封装的接口指针是否为=NULL,不是的话则.Release();
如果没错的话,上面的问题应该是出现在这里,至于具体原因
1. 为什么会出错
2. 为什么只是其中一个出错
我也不是很清楚,可能是释放内存的流程不同