65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIconstarIcon

5.00/5 (4投票s)

2002年2月19日

viewsIcon

76445

downloadIcon

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 文件以导出函数。

© . All rights reserved.