基于BCB环境的DLL使用ADO组件的研究.doc_第1页
基于BCB环境的DLL使用ADO组件的研究.doc_第2页
基于BCB环境的DLL使用ADO组件的研究.doc_第3页
基于BCB环境的DLL使用ADO组件的研究.doc_第4页
基于BCB环境的DLL使用ADO组件的研究.doc_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

基于BCB环境的DLL使用ADO组件的研究第19卷第1期2004年3月青岛大学(工程技术版)JOURNALOFQINGDAOUNIVERSITY(E&T)vO1.19NO.1Mar.2004文章编号:10069798(2004)01006505基于BCB环境的DLL使用ADO组件的研究张志梅(青岛大学信息工程学院,山东青岛266071)摘要:ADO组件不仅可以应用在C+Builder(BCB)创建的独立应用程序中,也可以应用在其创建的DLL中.利用ADO组件的原理,解决了在DLL中使用ADO组件时出现的异常情况,从而使得在BCB中创建的DLL可以正常使用ADO组件.关键词:ADO组件;DLL动态连接库;BCB中图分类号:TP311文献标识码:AADO(ActiveXDataObject)是微软提出的统一数据访问(UniversalDataAccess)技术中应用层的编程接口,它能够访问各种平台的数据库系统,并且还能访问文本文件,电子邮件等数据源的数据库引擎,是继ODBC之后又一数据访问技术的飞跃.ADO基于COM技术,建立在自动化(Automation)基础上,所以ADO的应用场合非常广泛,不仅可在VisualBasic这样的高级语言开发环境中使用,还可以在一些脚本语言中使用,这对于开发Web应用,在ASP(ActiveServerPage)的脚本代码访问数据库中提供了操作应用的捷径.Inprise公司在它的C+Builder(BCB)及Delphi中引入了ADO技术,并且对ADO进行了包装,形成了一套BCB环境中的ADO组件.这样BCB或Delphi的程序员访问数据库就有2条途径:ADO和BDE,并且BCB环境中的ADO组件的使用和BDE组件的使用非常相似,这样就使得原来熟悉BDE的程序员能很快转到ADO技术上.由于ADO具有轻量化,高性能的特点,所以利用BCB环境中的ADO组件构造客户机/服务器或多层数据库应用程序显得方便,快捷.然而,利用BCB创建动态连接库(DLL)时,如果在DLL中使用ADO组件,则会出现异常.1ADO技术原理应用程序要和ADO对象进行交互,必须遵循COM规范.在COM模型中,对象是通过接口及接口中的函数为客户提供服务的,对象本身对客户来说是不可见的,客户请求服务时,只能通过接口进行.每一个接口都有一个128位的GUID(全局唯一标识符),客户通过GUID获得接口指针,通过指针,客户就可以调用相应的函数.每一个COM对象也用一个128位的GUID来标识,称为CLSID,只要系统中包含这类COM对象的信息,并包括COM对象所在的容器(DLL或EXE文件)以及COM对象在代码中的入口点,客户程序就可以由CLSID来创建COM对象,并得到一个指向对象某个接口的指针u1J.要保证COM对象和客户程序之间通过接口在二进制代码级进行交互,必须在系统级提供支持.微软已经在Windows3.1,Windows95/98,WindowsNT,Windows2000和AppleMacintosh上提供了系统级的支持.这些系统级的支持称为COM库,以DLL文件的形式存在(ole32.dll和oleaut32.dl1),其中包括以下内容:1)提供了少量的API函数实现客户和服务器端COM应用的创建过程.在客户端,主要是一些创建函数;而在服务器端,提供一些对对象的访问支持.2)COM通过注册表查找COM对象的容器(DLL或EXE),及程序名与CLSID的转换.3)提供了一种标准的内存控制方法,使应用控制进程中内存的分配.收稿日期:20030627作者简介:张志梅(1969一),女,湖南湘乡人.讲师,主要研究方向为计算机应用.66青岛大学(工程技术版)第19卷COM库充当了组件程序和客户程序之间的桥梁,尤其在组件对象的创建过程中,以及在对象管理,内存管理和一些标准化操作等方面起着重要的作用.客户程序要想和COM对象交互,就不可避免地要调用COM库中的某些函数,然而在使用这些函数之前,必须调用COM库的初始化函数:HRESULTColnitialize(IMallocpMalloc);其中参数pMalloc用于指定一个内存分配器,它是一个IMalloc指针接IZl,可由客户程序指定内存分配原则.例如,可以限制COM库使用内存的总量,或者在COM库分配的内存中增加辅助信息等.一般情况下,该参数设置为NULL.这时COM库使用缺省的内存分配器.客户程序对COM库进行初始化之后,就可以调用COM库所提供的各种服务,在调用过程中必然要消耗由COM库管理的资源,尤其是一些影响系统全局的资源.因此在用完COM库服务之后,通常在程序退出之前,一定要调用终止COM库服务的函数,以便释放COM库所维护的资源.COM库的终止函数为:voidCoUninitialize(void);客户程序是在运行时刻与组件程序建立连接的,一旦连接起来以后,客户程序和组件程序的通信是直接进行的,并不需要COM库的参与,但组件程序的装载是在客户创建第一个组件对象时进行的,组件程序的卸载是在最后一个组件对象被释放之后进行的,组件程序的装载和卸载并不由客户程序完成,而是在COM库中完成的.ADO组件对象是建立在自动化技术上的,它也必然遵循上述COM的基本原理.因为自动化技术实际上只是COM的一个特例.当然,这里只是很粗略地叙述了一下COM原理,COM理论是一个非常复杂的技术.2BCB环境中ADO组件的使用Inprise公司在它的C+Builder(BCB)及Delphi中引入了ADO技术,并且对ADO进行了包装.形成了一套BCB环境中的ADO组件.BCB共提供了7个ADO组件2l,分别是:ADOConnection,ADOmmand,ADODataSet,ADOTable,ADOQuery,ADOStoredProc及RDSConnection.这些组件实际上是对微软提供的ADO组件对象进行了包装,使得ADO技术在BCB或Delphi环境中更加易于使用.这些组件的用法和BDE组件的用法非常相似(BDE是Inprise公司在引入ADO技术之前在BCB及Delphi中用来访问各种数据库的引擎),这样就使得原来熟悉BDE的程序员能很快转到ADO技术上.在BCB环境中创建独立的应用程序时,使用ADO组件非常简单,既可以在设计时通过在组件面板选择相应的组件放到窗体上,也可以在程序代码中直接使用ADO组件,以下是在程序代码中直接使用ADO组件的示例.例1:#include<adodb.hpp>voidfastcallTForml:ButtonlClick(TObjectSender)AnsiStringS=“Provider=SQLOLEDB.1;”;/微软针对SQLServer的OLEDB提供者S+:”DataSource=pdc;”;/数据库服务器名称S+=“InitialCatalog=dbtest;”;/数据库名称S+:”UserID=sa;”;/数据库帐号S+=“Password=1234;”:TADOQueryquery=NULL;query:newTADOQuery(NULL);query一>ConnectionString=s;第1期张志梅:基于BCB环境的DLL使用ADO组件的研究67query一>SQL一>Addf”select*query一>Open();这是在一个独立的应用程序中使用ADO的示例,在C+Builer6中编译,连接,运行,一切正常.在实际应用中,可能需要在一个DLL中使用ADO.例2:#include<adodb.hpp>extern”C”一declspec(dllexport)boolstdealldlladotest();boolstdealldlladotest()AnsiStrings=“Provider=SQLOLEDB.1;”;/微软针对SQLServer的OLEDB提供者S+=“DataSource=pdc;”;/数据库服务器名称S+=“InitialCatalog=dbtest;”;/数据库名称S+=“UserID=sa;”;/数据库帐号S+=“Password=1234:”;TADOQueryquery=NULL:query=newTADOQuery(NULL);query一>ConnectionString=S:query一>SQL一>Add(“select*fromtest”);query一>Open();例2在一个DLL中引出了一个函数dlladotest,这个函数的代码和例1中的完全相同,在编译,连接时完全正常.假定生成的动态连接库文件为adotest.dll,例3展示了在VB中如何调用该函数,例4展示了在VFP中如何调用,例5展示了在BCB中如何调用.例3:PrivateDeclareFunctiondlladotestLib”adotest”()AsBooleanPrivateSubCommandlClick()Ifdlladotest()ThenMsgBox(“调用dlladotest正常”)ElseMsgBox(“调用dlladotest时发生错误”)EndIfEndSub例4:declareintegerdlladoifdlladotest()=1messagebox(“调用dllelsemessagebox(“调用dUendifadotest正常”)adotest时发生错误”)青岛大学(工程技术版)第19卷例5:HINSTANCElib;bool(stdcall*dlladotest)();lib=LoadLibrary(“adotest.dll”);dlladotest=(bool(stdcall*)(char*)GetProcAddress(1ib,”dlladotest”);if(dlladotest()ShowMessage(“调用dlladotest正常”);elseShowMessage(“调用dlladotest时发生错误”);运行例3,例4及例5时发现,在VB或VFP中,调用该DLL中的dlladotest函数时正常,但是在BCB中调用该函数却出现异常.经过研究分析,VB或VFP属于弱类型语言,也正是为了使这些弱类型语言方便地访问COM对象,才诞生了自动化(Automation)技术,这些语言本身封装并隐藏了大量访问COM对象的细节,其中包括对COM库的调用.然而在VC+或c+Builder编写的应用程序中想要访问COM对象,情况就要复杂一些,根据前面对COM原理的介绍,客户程序访问COM对象,一般要经过以下步骤:1)初始化COM库,即调用CoInitialize函数.2)用COM对象的CLSID,调用CoCreatelnstane函数加载COM对象所在的容器(DLL或EXE),并创建COM对象.3)客户程序使用COM对象.4)调用CoFreeUnusedLibraries函数卸载COM对象所在的容器.5)调用COM库的终止函数CoUninitialize.当然也可以利用MFC库提供的Idispatch接口封装类ColeDispatchDriver在VC+中创建和调用ADO对象.前面也曾提到,在c+Builder中提供的ADO组件是对微软提供的ADO对象进行的包装,使得在BCB中创建ADO这样的COM对象时,和普通的VCL组件对象相似,也就是说隐藏了上述客户程序访问COM对象的一般步骤.Inprise公司的这种包装却存在一个瑕疵,也许是一个Bug,这就是在前面例1中独立的应用程序中使用ADO组件时没有问题,但在DLL中使用ADO组件时却出现异常.解决这个问题的方法很简单,只需在例2中加入初始化COM库的语句即可,见例6.例6:#include<adodb.hpp>extern”C”一declspec(dllexport)boolstdcalldlladotest();boolstdcalldlladotest()AnsiStringS=“Provider=SQLOLEDB.1;”;/微软针对SQLServer的OLEDB提供者S+=“DataSource=pdc;”;/数据库服务器名称S+=“InitialCatalog=dbtest;”;/数据库名称S+=“UserID=sa;”;/数据库帐号S+=“Password=1234:”:HRESULT,coret=Colnitialize(NULL);/初始化COM库if(coret!=SOK&&coret!=SFALSE)returnfalse;TADOQueryquery=NULL:query=newTADOQuery(NULL);query一>ConnectionString=S:第1期张志梅:基于BCB环境的DLL使用ADO组件的研究69query一>SQL一>Add(“select*fromtest”);query一>O

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论