可在 ANSI-C 中使用的 OLE-DB DLL





5.00/5 (4投票s)
2002年2月19日

76445

750
可在 ANSI-C 中使用的 OLE-DB DLL
引言
我使用名为 Labwindows/CVI 的 ANSI-C 编译工具进行编程。我的操作系统是 Windows 2k 高级服务器。 大家都知道 ANSI-C 不能使用 OLE-DB,但 Win2k 操作系统支持它。 因此,我认为可以通过 DLL 文件让 CVI 支持 OLE-DB。 最后我成功了,方法如下。
详细说明
首先使用向导创建一个 MFC DLL 项目。 然后更新 stdafx.h 文件。
#define VC_EXTRALEAN // Exclude rarely-used stuff // from Windows headers #include <AFXWIN.H> // MFC core and standard components #include <AFXEXT.H> // MFC extensions #include <AFXCVIEW.H> #include <AFXDISP.H> // MFC Automation classes #include <AFXDTCTL.H> // MFC support for Internet Explorer // 4 Common Controls #import "c:\program files\common files\system\ado\msado15.dll" \ no_namespace \ rename ("EOF", "adoEOF")
最后一条语句可以让项目支持 ADO ole-db 版本 2。 类 cTestCpp
(抱歉,我为这个项目起了一个测试名称)完成了主要工作,而 testDll.c 完成了接口工作。
代码列表
class cTestCpp { public: int Execute(const char *sql,int *AffectedRecord); int CloseRst(void); int CloseConn(void); BOOL IsBof(void); BOOL IsEof(void); int GetCount(int *iResult); int MoveLast(void); int MoveFirst(void); int MovePrevious(void); int Movenext(void); int openConn(const char *connStr); void test(void); int DBConnect(const char *strConn); int CreateRst(void); int openRst(const char *sql); int getCol(const char *colName,int dataType,char *result); cTestCpp(); //Construction virtual ~cTestCpp(); //Destruction private: _ConnectionPtr m_pConnection; //The Ole-DB Connection _RecordsetPtr pRecordSet; //The RecordSet that contain the record }; // cTestCpp.cpp: implementation of the cTestCpp class. // //////////////////////////////////////////////////////////// #include "stdafx.h" #include "cTestCpp.h" //#include "msado15.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// cTestCpp::cTestCpp(){ if (!AfxOleInit()) { AfxMessageBox("ole Init Error"); return ; } CoInitialize(NULL); } int cTestCpp::DBConnect(const char *strConn) { return 0; } cTestCpp::~cTestCpp() { CoUninitialize(); } int cTestCpp::openConn(const char *connStr) { try{ HRESULT hr; hr = m_pConnection.CreateInstance( __uuidof( Connection ) ); if (SUCCEEDED(hr)){ hr = m_pConnection->Open( _bstr_t(connStr), _bstr_t(L""), _bstr_t(L""), adModeUnknown); return 0; } } catch (...) { return -1; } return -1; } int cTestCpp::CreateRst() { HRESULT hr; hr=pRecordSet.CreateInstance( __uuidof(Recordset)); if(SUCCEEDED(hr)){ return 0; } pRecordSet->Release(); return -1; } int cTestCpp::openRst(const char *sql) { _variant_t vRecsAffected(0L); _bstr_t bstrQuery(sql); HRESULT hr; _variant_t vNull; vNull.vt = VT_ERROR; vNull.scode = DISP_E_PARAMNOTFOUND; try{ hr = pRecordSet.CreateInstance(__uuidof(Recordset)); if (SUCCEEDED(hr)) { pRecordSet->PutRefActiveConnection(m_pConnection); hr = pRecordSet->Open(_variant_t(bstrQuery), vNull, adOpenForwardOnly, adLockOptimistic, adCmdText); } } catch(...){ return -1; } return 0; } int cTestCpp::getCol(const char *colName,int dataType,char *result) { try{ _variant_t ss; CString s; ss = pRecordSet->GetCollect(colName); switch(dataType) { case INTEGER_TYPE: s.Format("%d",ss.intVal); break; case STRING_TYPE: s=CString(ss.bstrVal); break; case DOUBLE_TYPE: s.Format("%f",ss.dblVal); break; case DATE_TYPE: s.Format("%s",ss.date); default: s="error data type"; } strcpy(result,(const char*)s); } catch(...){ return -1; } return 0; } int cTestCpp::Movenext() { try{ pRecordSet->MoveNext(); } catch(...){ return -1; } return 0; } int cTestCpp::MovePrevious() { try{ pRecordSet->MovePrevious(); } catch(...){ return -1; } return 0; } int cTestCpp::MoveFirst() { try{ pRecordSet->MoveFirst(); } catch(...){ return -1; } return 0; } int cTestCpp::MoveLast() { try{ pRecordSet->MoveLast(); } catch (...) { return -1; } return 0; } int cTestCpp::GetCount(int *iResult) { try{ *iResult=pRecordSet->GetRecordCount(); } catch (...) { return -1; } return 0; } BOOL cTestCpp::IsEof(void){ VARIANT_BOOL bl; try{ bl=pRecordSet->GetadoEOF(); } catch (...) { return FALSE; } return bl; } BOOL cTestCpp::IsBof() { VARIANT_BOOL bl; try{ bl=pRecordSet->GetBOF(); } catch (...) { return FALSE; } return bl; } int cTestCpp::CloseConn() { HRESULT hr; try{ hr=m_pConnection->Close(); m_pConnection.Release(); if(!SUCCEEDED(hr)){ return -1; } } catch (...) { return -1; } return 0; } int cTestCpp::CloseRst() { HRESULT hr; try{ hr = pRecordSet->Close(); pRecordSet.Release(); if(!SUCCEEDED(hr)){ return -1; } } catch (...) { return -1; } return 0; } int cTestCpp::Execute(const char *sql, int *AffectedRecord) { _variant_t vRecsAffected(0L); _bstr_t bstrQuery(sql); try{ m_pConnection->Execute(bstrQuery, &vRecsAffected, adOptionUnspecified); } catch (...) { return -1; } *AffectedRecord=vRecsAffected.intVal; return 0; }
以及接口代码。
// testDll.cpp : Defines the entry point for the DLL application. // #include "stdafx.h" #include "testDll.h" #include "cTestCpp.h" int openConn(const char *connstr){ return test.openConn(connstr); } int CreateRst(void){ return test.CreateRst(); } int openRst(const char *sql){ return test.openRst(sql); } int getCol(const char *colName,int dataType,char *result){ return test.getCol(colName,dataType,result); } int movenext(){ return test.Movenext(); } int movePrevious(){ return test.MovePrevious(); } int moveFirst(){ return test.MoveFirst(); } int moveLast(){ return test.Movenext(); } int GetCount(int *iResult){ return test.GetCount(iResult); } BOOL IsEof(){ return test.IsEof(); } BOOL IsBof(){ return test.IsBof(); } int closeConn(){ return test.CloseConn(); } int closeRst(){ return test.CloseRst(); } int Execute(const char *sql, int *AffectedRecord){ return test.Execute(sql,AffectedRecord); }
在接口代码中,所有参数都是 const char*
,因为 ANSI 代码不支持 CString
类等。 最后,我们更新 testDll.def 文件以导出函数。