设为首页 加入收藏

TOP

VC++程序员如何阅读ADO文档(二)
2012-11-04 15:24:23 来源: 作者: 【 】 浏览:1449
Tags:程序员 如何 阅读 ADO 文档


  COM特定的数据类型

  一般的,你在《ADO API Reference》中看到的VB的数据类型在VC++(www.cppentry.com)中也能找到对应的类型。其中包括标准的数据类型,比如unsigned char对应VB的Byte,short对应Integer,long对应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型参数会被构造,无论你传递的是一个类似"DSN=pubs;uid=sa;pwd=;"这样的字符串,或者是一个类似"(IDispatch *) pConn"的指针。

  或者你还可以显式的编写"_variant_t((IDispatch *) 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++(www.cppentry.com)数组。

  比如,Connection对象的OpenSchema方法的第二个参数需要一个由Variant值组成的数组。这些Variant值必须作为一个SafeArray数组的元素进行传递。而这个SafeArray数组本身又被作为一个Variant进行传递。

  更进一步的,Find方法的第一个参数是一个指向一维SafeArray数组的Variant;AddNew方法的可选的第一与第二个参数也是一个一维的SafeArray数组;GetRows方法的返回值则是一个包含二维SafeArray数组的Variant。

  缺省参数

  VB允许省略方法的某些参数。例如,Recordset对象的Open方法有五个参数,但是你可以跳过中间的参数并省略之后的参数。被省略的参数会被自动创建的BSTR或Variant缺省值替代。

  在C/C++(www.cppentry.com)中,所有的操作数必须被明确。如果你想定义一个字符串型的缺省参数,那么就定义一个包含空字符串的_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->Execute("commandText", NULL, adCmdText);
pCommand->Execute(NULL, NULL, adCmdText);
pRecordset->NextRecordset(NULL);

  错误的处理

  在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++(www.cppentry.com)扩展》以及本文后续的示例代码。

首页 上一页 1 2 3 4 5 6 7 下一页 尾页 2/8/8
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇用VC++实现连续播放多媒体软件 下一篇用Visual C++打造IE浏览器

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: