An OLE-DB DLL that you can use in ANSI-C





5.00/5 (4 votes)
Feb 19, 2002

75905

750
An OLE-DB DLL that you can use in ANSI-C
Introduction
I program with a ansi-c compile tools named Labwindows/CVI. My OS is Windows 2k advance server. Everyone know that ANSI-C can not use OLE-DB but the Win2k OS support it. So I think I can let the CVI support the OLE-DB through DLL file. And finally I succeeded and here is how.
Details
First Use Wizard Create a MFC DLL project. And then update the stdafx.h file.
#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")
The last statement can let the project support the ADO ole-db version 2. The class cTestCpp
(sorry , I made a test name for this project) does the main work and the testDll.c does the interface work.
Code Listings
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; }
And the interface code.
// 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); }
In the interface code all parameter is the const char*
, because the ansi code can not support CString
class etc. At last, we update the testDll.def file to export the function.