我想在DLL中建立对话框并使用ADO访问数据库来输入数据,但是发现在DLL中无法创建有效的ADO指针。以最小代码进行了测试也还是如此,所以上来发帖求教。以下是DLL的最小测试代码!另外在DLL中使用ADO需要使用命名空间,不知为什么。如上:
#pragma warning(disable:4146)
#import "C:\Program Files\Common Files\System\ado\msado15.dll" named_guids rename("EOF","adoEOF")
#pragma warning(default:4146)
using namespace ADODB;
/////////////////////////////////////////////////////////////////
我使用的是常规MFC DLL,输出函数,在DLL访问这个函数来运行对话框。代码如下:
class Runmyado
{
public:
_ConnectionPtr m_pConnection;
BOOL RunOpen ()
{
HRESULT t_hr;
try
{
t_hr = m_pConnection.CreateInstance("ADODB.Connection");///创建Connection对象
// 打开本地Access库Demo.mdb
if(SUCCEEDED(t_hr))
{
m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Count.mdb","","",adModeUnknown);
}
else
{
return FALSE;
}
}
catch(_com_error e)
{
CString errormessage;
errormessage.Format((_T("连接数据库失败!\r\n错误信息:%s")),e.ErrorMessage());
AfxMessageBox(errormessage);///显示错误信息
//DestroyWindow ();
return FALSE;
}
return TRUE;
}
};extern "C" BOOL _declspec(dllexport) GoAdo ()
{
Runmyado t_myado;
if (t_myado.RunOpen ())
{
AfxMessageBox ("程序正常运行!");
return TRUE;
}
return FALSE;
}
#pragma warning(disable:4146)
#import "C:\Program Files\Common Files\System\ado\msado15.dll" named_guids rename("EOF","adoEOF")
#pragma warning(default:4146)
using namespace ADODB;
/////////////////////////////////////////////////////////////////
我使用的是常规MFC DLL,输出函数,在DLL访问这个函数来运行对话框。代码如下:
class Runmyado
{
public:
_ConnectionPtr m_pConnection;
BOOL RunOpen ()
{
HRESULT t_hr;
try
{
t_hr = m_pConnection.CreateInstance("ADODB.Connection");///创建Connection对象
// 打开本地Access库Demo.mdb
if(SUCCEEDED(t_hr))
{
m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Count.mdb","","",adModeUnknown);
}
else
{
return FALSE;
}
}
catch(_com_error e)
{
CString errormessage;
errormessage.Format((_T("连接数据库失败!\r\n错误信息:%s")),e.ErrorMessage());
AfxMessageBox(errormessage);///显示错误信息
//DestroyWindow ();
return FALSE;
}
return TRUE;
}
};extern "C" BOOL _declspec(dllexport) GoAdo ()
{
Runmyado t_myado;
if (t_myado.RunOpen ())
{
AfxMessageBox ("程序正常运行!");
return TRUE;
}
return FALSE;
}
#import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF","adoEOF")
2。app文件的InitInstance中加入
if(S_OK!=OleInitialize(NULL)) //或者CoInitialize()
{
AfxMessageBox("初始化COM组件库错误");
}
下面就是数据库操作
_ConnectionPtr pConn;
_RecordsetPtr pRs;
CString strSQL;
pConn.CreateInstance(__uuidof(Connection));
pConn->CursorLocation=adUseClient;
strSQL="Provider=SQLOLEDB;Server=Gooyan;DataBase=SkillsBox;UID=sa;PWD=aaaaaaaa";
pConn->Open(_bstr_t(strSQL),"","",-1);pRs.CreateInstance(__uuidof(Recordset));
pRs->CursorLocation=adUseClient;
pRs->PutActiveConnection(pConn.GetInterfacePtr());pRs1.CreateInstance(__uuidof(Recordset));
pRs1->CursorLocation=adUseClient;
pRs1->PutActiveConnection(pConn.GetInterfacePtr());strSQL="select * from catalog order by cataid";
pRs->Open(_bstr_t(strSQL),vtMissing,adOpenDynamic,adLockBatchOptimistic,adCmdText);
在 PROCESS_DETACH 之前 CoUninitialize();
// For DLLs where this is not the case, those DLLs will need to initialize
// OLE for themselves via OleInitialize. This is done since MFC cannot provide
// automatic uninitialize for DLLs because it is not valid to shutdown OLE
// during a DLL_PROCESS_DETACH.
if (afxContextIsDLL)
{
pState->m_bNeedTerm = -1; // -1 is a special flag
return TRUE;
}
因为 MFC 中的实现是
BOOL AFXAPI AfxOleInit()
{
_AFX_THREAD_STATE* pState = AfxGetThreadState();
ASSERT(!pState->m_bNeedTerm); // calling it twice? if (afxContextIsDLL)
{
pState->m_bNeedTerm = -1; // -1 is a special flag
return TRUE;
}
而 afxContextIsDLL 的定义是 #define afxContextIsDLL AfxGetModuleState()->m_bDLL
大概此时的 m_bDLL 为 FALSE 吧,但这样使用可能会有一些不安全的因素
CoUninitialize()