Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

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

0.00/5 (No votes)
3 Jul 2002 3  
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.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here