学会使用safearray也是很重要的,因为在ado编程中经常要用。它的主要目的是用于automation中的数组型参数的传递。因为在网络环境中,数组是不能直接传递的,而必须将其包装成safearray。实质上safearray就是将通常的数组增加一个描述符,说明其维数、长度、边界、元素类型等信息。safearray也并不单独使用,而是将其再包装到variant类型的变量中,然后才作为参数传送出去。在variant的vt成员的值如果包含vt_array|...,那么它所封装的就是一个safearray,它的parray成员即是指向safearray的指针。safearray中元素的类型可以是variant能封装的任何类型,包括variant类型本身。
使用safearray的具体步骤:
方法一:
包装一个safearray:
(1). 定义变量,如:
variant varchunk;
safearray *psa;
safearraybound rgsabound[1];
(2). 创建safearray描述符:
uisread=f.read(bval,chunksize);//read array from a file.
if(uisread==0)break;
rgsabound[0].celements =uisread;
rgsabound[0].llbound = 0;
psa = safearraycreate(vt_ui1,1,rgsabound);
(3). 放置数据元素到safearray:
for(long index=0;index<uisread;index++)
{
if(failed(safearrayputelement(psa,&index,&bval[index])))
::messagebox(null,"出毛病了。","提示",mb_ok | mb_iconwarning);
}
一个一个地放,挺麻烦的。
(4). 封装到variant内:
varchunk.vt = vt_array|vt_ui1;
varchunk.parray = psa;
这样就可以将varchunk作为参数传送出去了。
读取safearray中的数据的步骤:
(1). 用safearraygetelement一个一个地读
byte buf[lisread];
for(long index=0;index<lisread;index++)
{
::safearraygetelement(varchunk.parray,&index,buf+index);
}
就读到缓冲区buf里了。
方法二:
使用safearrayaccessdata直接读写safearray的缓冲区:
(1). 读缓冲区:
byte *buf;
safearrayaccessdata(varchunk.parray, (void **)&buf);
f.write(buf,lisread);
safearrayunaccessdata(varchunk.parray);
(2). 写缓冲区:
byte *buf;
::safearrayaccessdata(psa, (void **)&buf);
for(long index=0;index<uisread;index++)
{
buf[index]=bval[index];
}
::safearrayunaccessdata(psa);
varchunk.vt = vt_array|vt_ui1;
varchunk.parray = psa;
这种方法读写safearray都可以,它直接操纵safearray的数据缓冲区,比用safearraygetelement和safearrayputelement速度快。特别适合于读取数据。但用完之后不要忘了调用::safearrayunaccessdata(psa),否则会出错的。