【vb精品源码栏目提醒】:网学会员,鉴于大家对vb精品源码十分关注,论文会员在此为大家搜集整理了“VC++程序员应当如何阅读ADO文档(1) - 计算机教材”一文,供大家参考学习!
《ADO API参考》用
VB的语法描述了ADO API的内容。
但ADO程序员却使用着不同的编程语言比如VBVCVJ。
对此《ADO for VC的语法索引》提供了符合VC语法规范的详细描述包括功能、参数、异常处理等等。
ADO基于若干的COM借口实现因此它的使用对于一个正进行COM编程的程序员而言更简单。
比如几乎所有使用COM的细节对于
VB程序员而言都是隐藏了的但对于VC程序员而言却要特别注意。
以下是对于C和C程序员使用ADO和import指示符方面的概述主要描述了COM使用的数据类型Variant BSTR and SafeArray和异常的处理_com_error。
使用import编译指示符 import编译指示符使使用ADO的方法与属性简单化。
这个指示符需要一个类型库文件名比如ADO.dllMsado15.dll并生成对应的头文件其中包括定义的类型、接口的智能化指针、常量。
并且所有的接口都被封装成类。
对于类中的每个操作或称方法、属性调用都有一个声明以保证能直接调用它或称作操作的源形式以及另一个声明来调用这个源操作并在操作失败时抛出一个COM错误。
如果操作是一个属性那么编译指示符可以为该操作创建一个可交互的类似
VB的语法形式。
返回/设置属性的操作有对应的形式化的名字—GetProperty/PutPropert而设置一个指向某个ADO对象的指针型属性值时则是PutRefProperty。
你将使用如下的形式读写属性的值 variable objectPtr-GetProperty // 读取属性的值 objectPtr-PutPropertyvalue // 设置属性的值 objectPtr-PutRefPropertyvalue // 设置一个指针型的属性的值 直接使用属性 __declspecproperty...编译指示符是微软定义的一个针对C语言的扩展使一个函数象一个属性那样被使用。
这样你就可以采用如下的语法形式象在使用
VB一样读写一个属性的值 objectPtr-property value // 设置属性的值 variable objectPtr-property // 读取属性的值 __declspecproperty...编译指示符只能针对属性的读写函数使用并根据属性是否可供读写自动生成对应的调用形式。
每个属性可能有GetProperty PutPropertyPutRefProperty三个函数但这个编译符只能生成其中的两种交互形式。
比如Command对象的ActiveConnection属性有GetActiveConnection和PutRefActiveConnection这两个读写函数。
而PutRef-的形式在实践中是个好的选择你可以将一个活动的Connection对象的指针保存在这个属性中。
另一方面Recordset对象则有Get- Put- and PutRefActiveConnection操作但却没有可交互的语法形式。
CollectionsGetItem方法和Item属性 ADO定义了几种集合Collection包括FieldsParametersProperties和Errors。
在Visual C中GetItemindex方法返回Collection中的某个成员。
Index是一个Variant型的参数内容可以是一个该成员对应的序数也可以是一个包括其名称的字符串。
__declspecproperty...编译指示符为Item属性生成对应于GetItem方法的直接使用形式上文提到的可交互的语法形式。
这种形式类似于引用数组元素时使用的语法形式 collectionPtr-GetItemindex collectionPtr-Itemindex 举例说明要给一个Recordset对象rs中的某个字段赋值而这个Recordset对象派生于pubs数据库中的authors表。
使用Item属性访问这个Recordset的Fields集合中的第三个字段集合总是从0开始编号假设第三个字段名为au_fname。
然后调用Value方法为该字段赋一个字符串值。
Visual Basic的语法形式 rs.Fields.Item2.Value value rs.Fields.Itemau_fname.Value value 或者 rs2 value rsau_fname value Visual C的语法形式 rs-Fields-GetItem2-PutValuevalue rs-Fields-GetItemau_fname-PutValuevalue 或者 rs-Fields-Item2-Value value rs-Fields-Itemau_fname-Value value COM特定的数据类型 一般的你在《ADO API Reference》中看到的
VB的数据类型在VC中也能找到对应的类型。
其中包括标准的数据类型比如unsigned char对应
VB的Byteshort对应Integerlong对应Long。
参见《Syntax Indexes》将可以获得关于所需操作数的更详细内容。
而作为例外的专属于COM使用的数据类型则有Variant BSTR and SafeArray. Variant Variant是一个结构化的数据类型包含了一个成员值及其数据类型的表示。
Variant可以表示相当多的数据类型甚至另一个Variant BSTR Boolean Idispatch或Iunknown指针货币日期等等。
同时COM也提供了许多方法使数据类型间的转换更简单化。
_variant_t类封装并管理Variant这一数据类型。
当《ADO API Reference》中说到一个方法或属性要使用一个参数时通常意味着需要一个_variant_t类型的参数。
这条准则在《ADO API Reference》的Parameters一章中得到了明白无误的表述。
作为例外的是有时则会要求操作数是一个标准的数据类型比如Long或Byte 或者一个枚举值。
另一个例外是要求操作数是一个字符串String。
BSTR BSTR Basic STRing也是一个结构化的数据类型包括了串及串的长度。
COM提供了方法进行串的空间分配、操作、释放。
_bstr_t类封装并管理BSTR这一数据类型。
当《ADO API Reference》中说到一个方法或属性要使用一个字符串参数时通常意味着需要一个类_bstr_t型的参数。
_variant_t和_bstr_t类的强制类型转换 通常当传递一个_variant_t或_bstr_t参数给一个操作时并不需要显式的类型转换代码。
如果_variant_t或_bstr_t类提供了对应于该参数类型的构造函数那么编译器将会自动生成适当的_variant_t或_bstr_t值。
然而当参数模棱两可时即对应了多个构造函数时你就必须显式地调用正确的构造函数以获得正确的参数。
比如Recordset::Open方法的函数声明如下 HRESULT Open const _variant_t Source const _variant_t ActiveConnection enum CursorTypeEnum CursorType enum LockTypeEnum LockType long Options 其中参数ActiveConnection就是针对一个variant_t型变量的引用它可以是一个连接串或者一个指向已打开的Connection对象的指针。
正确的_variant_t型参数会被构造无论你传递的是一个类似DSNpubsuidsapwd这样的字符串或者是一个类似IDispatch pConn的指针。
或者你还可以显式的编写_variant_tIDispatch pConn true这样的代码来传递一个包含指针的_variant_t变量。
这里的强制类型转换IDispatch 避免了可能调用IUnknown接口构造函数的模棱两可性。
虽然很少提及但特别重要的是ADO总是一个IDispatch接口。
任何被传递的被包含在Variant中的指针都必须被转换为一个IDispatch接口指针。
最后需要说明的是构造函数的第二个逻辑参数是可选择的它的缺省值是True。
这个参数将决定Variant的构造函数是否调用内嵌的AddRef方法并在完成ADO的方法或属性调用后是否自动调用_variant_t::Release方法 SafeArray SafeArray也是一种结构化的数据类型包含了一个由其它数据类型的数据元素组成的数组。
之所以称之为安全的数组是因为它包含了每一维的边界信息并限制在边界内进行数组元素的访问。
当《ADO API Reference》中说到一个方法或属性要使用或者返回一个数组时通常意味着是一个SafeArray数组而非一个本地化的C/C数组。
比如Connection对象的OpenSchema方法的第二个参数需要一个由Variant值组成的数组。
这些Variant值必须作为一个SafeArray数组的元素进行传递。
而这个SafeArray数组本身又被作为一个Variant进行传递。
更进一步的Find方法的第一个参数是一个指向一维SafeArray数组的VariantAddNew方法的可选的第一与第二个参数也是一个一维的SafeArray数组GetRows方法的返回值则是一个包含二维SafeArray数组的Variant。
缺省参数
VB允许省略方法的某些参数。
例如Recordset对象的Open方法有五个参数但是你可以跳过中间的参数并省略之后的参数。
被省略的参数会被自动创建的BSTR或Variant缺省值替代。
在C/C中所有的操作数必须被明确。
如果你想定义一个字符串型的缺省参数那么就定义一个包含空字符串的_bstr_t。
如果想定义一个Variant型的缺省参数那么就定义一个值为DISP_E_PARAMNOTFOUND、类型为VT_ERROR的_variant_t。
你还可以使用import编译指示符提供的与之等价的常量vtMissing。
vtMissing的使用有三种意外情形Connection与Command对象的Execute方法Recordset对象的NextRecordset方法。
_RecordsetPtr Execute _bstr_t CommandText VARIANT RecordsAffected long Options // Connection _RecordsetPtr Execute VARIANT RecordsAffected VARIANT Parameters long Options // Command _RecordsetPtr NextRecordset VARIANT RecordsAffected // Recordset 参数RecordsAffected与Parameters都是指向Variant的指针。
Parameters是一个传入参数指向一个包含一个或一组参数信息的Variant的地址将决定命令执行的内容。
RecordsAffected是一个传出参数指向一个包含该方法返回时影响行的数目的Variant的地址。
在Command对象的Execute方法中如果只是没有参数的话需要将Parameters设置为vtMissing 推荐使用或者一个空指针NULL。
如果传递的是一个空指针那么等价的vtMissing会被传递并完成操作。
在所有的方法中通过设置RecordsAffected为空指针可以指示不需返回被影响的记录的数目。
此时这个空指针实际成为了指示该方法抛弃被影响记录数目的指示器。
因此如下的编码是有效的 pConnection-ExecutecommandText NULL adCmdText pCommand-ExecuteNULL NULL adCmdText pRecordset-NextRecordsetNULL 错误的处理 在COM中大多数的操作总是返回一个HRESULT值说明该函数是否被成功完成。
编译指示符import为所有源方法和属性提供了封装好的代码并检查返回的HRESULT值。
如果HRESULT指示失败这些封装代码将会通过调用以HRESULT为参数的_com_issue_errorex抛出一个COM错误。
COM错误对象将在try-catch块中被捕获出于效率的考虑实际捕获的是一个_com_error对象的引用指针。
记住由ADO操作失败产生的错误才是ADO错误。
由下层提供者返回的错误以Connection对象中Errors集合中的一个Error对象的形式出现。
编译指示符import只能为在ADO.dll中声明的方法和属性提供错误处理例程。
因此你可以基于同样的错误处理机制编写自己的错误检查宏或内置函数。
参见《Visual C扩展》以及本文后续的示例代码。