利用(IDispatch *)转换ADO对象的指针类型
1.在一个Variant中显式地封装一个活动的Connection对象,然后用(IDispatch *)进行类型转换确保正确的构造函数被调用。同时明确地设置第二个参数为缺省的true,使该对象的引用计数在Recordset::Open操作完成后仍得到正确的维护。
2.表达式(_bstr_t)不是一个类型转换,而是一个_variant_t的操作符,用以从中提取一个_bstr_t字符串。
表达式(char*)也不是一个类型转换,而是一个_bstr_t的操作符,用以从中提取封装在_bstr_t中的字符串的指针。
下面这些代码演示了_variant_t和_bstr_t的一些常见操作。
#import "c:\Program Files\Common Files\System\ADO\msado15.dll"
no_namespace rename("EOF", "EndOfFile")
#include <stdio.h>
void main(void) {
CoInitialize(NULL);
try
{ _ConnectionPtr pConn("ADODB.Connection");
_RecordsetPtr pRst("ADODB.Recordset");
pConn->Open("Provider=sqloledb;Data Source=a-tima10;"
"Initial Catalog=pubs;User Id=sa;Password=;",
"", "", adConnectUnspecified);
// Note 1
pRst->Open(
"authors",
_variant_t((IDispatch *) pConn, true),
adOpenStatic,
adLockReadOnly,
adCmdTable);
pRst->MoveLast();
// Note 2
printf("Last name is '%s %s'\n",
(char*) ((_bstr_t) pRst->GetFields()->GetItem("au_fname")->GetValue()),
(char*) ((_bstr_t) pRst->Fields->Item["au_lname"]->Value));
pRst->Close();
pConn->Close();
}
catch (_com_error &e)
{
printf("Description = '%s'\n", (char*) e.Description());
}
::CoUninitialize();
}
///////////////////////////////////////////////
VC++对ADO的扩展
///////////////////////////////////////////////
对于VC++程序员而言,每次都要将ADO返回的数据转换成一般的C++数据类型,接着将数据存入一个类或结构总是一件枯燥的事。更讨厌的是这也带来了效率的低下。
因此,ADO提供了一个接口以支持将数据直接返回为一个本地化的C/C++数据类型而非VARIANT,并提供了一系列的预处理宏来方便使用这些接口。这样做的结果是一个复杂的工具可以很轻松的被使用并能获得很好的性能。
一个普通的C/C++客户场景是将一个Recordset中的一条记录绑定到一个包含本地C/C++数据类型的C/C++结构或类之上。如果通过Variant传递数据,这意味着要编写大量的转换代码,以在VARIANT和C/C++本地类型间进行数据转换。VC++对ADO的扩展出现的目的就是要简化这一过程。
如何使用VC++对ADO的扩展
IADORecordBinding接口
VC++对ADO的扩展联系或绑定了一个Recordset对象的各个字段到C/C++变量。当被绑定的Recordset的当前行改变时,其中所有被绑定的字段的值也同样会被拷贝到相应的C/C++变量中。如果需要,被拷贝的数据还会自动进行相应的数据类型转换。
IADORecordBinding接口的BindToRecordset方法将字段绑定到C/C++变量之上。AddNew方法则是增加一个新的行到被绑定的Recordset。Update方法利用C/C++变量的值填充Recordset中新的行或更新已存在的行。
IADORecordBinding接口由Recordset对象实现,你不需要自己编码进行实现。
绑定条目
VC++对ADO的扩展在一个Recordset对象与一个C/C++变量间进行映像(Map)。一个字段与对应的一个变量间的映像被称作一个绑定条目。预定义的宏为数字、定长或不定长数据提供了绑定条目。所有的绑定条目与相应的C/C++变量都被封装、声明在一个从VC++扩展类CADORecordBinding派生的类中。这个CADORecordBinding类在内部由绑定条目宏定义。
在ADO内部,将所有宏的参数都映射在一个OLE DB DBBINDING结构中,并创建一个OLE DB访问子(Accessor)对象来管理所有的行为和字段与变量间的数据转换。OLE DB定义的数据由以下三部分组成:存储数据的缓冲区;一个状态值表示一个字段是否被成功地被存入缓冲区,或变量值是否被成功地存入字段;数据长度。(参见OLE DB程序员参考第6章:读写数据的更多信息)
所需的头文件
为了使用VC++对ADO的扩展,你得在你的应用中包含这个头文件:#include <icrsint.h>
绑定Recordset的字段
要绑定Recordset的字段到C/C++变量,需要这样做:
1.创建一个CADORecordsetBinding的派生类。
2.在派生类中定义绑定条目和相应的C/C++变量。注意不要使用逗号、分号切断宏。每个宏都会自动地定义适当的分隔符。
为每个被映像的字段定义一个绑定条目。并注意根据不同情况选用ADO_FIXED_LENGTH_ENTRY、 ADO_NUMERIC_ENTRY、ADO_VARIABLE_LENGTH_ENTRY中的某个宏。
3.在你的应用中,创建一个该派生类的实例。从Recordset中获得IADORecordBinding接口,然后调用BindToRecordset方法将Recordset的所有字段绑定到对应的C/C++变量之上。
请参见示例程序以获得更多信息。
接口方法
IADORecordBinding接口只有三个方法:BindToRecordset, AddNew,和Update。每个方法所需的唯一的参数就是一个CADORecordBinding派生类的实例指针。因此,AddNew和Update方法不能使用任何与它们同名的ADO方法中的参数。
语法
BindToRecordset方法将字段绑定到C/C++变量之上。
BindToRecordset(CADORecordBinding *binding)
AddNew方法则引用了它的同名ADO函数,来增加一个新的记录行。
AddNew(CADORecordBinding *binding)
Update方法也引用了它的同名ADO函数,来更新Recordset。
Update(CADORecordBinding *binding)
|