SafeArray

SafeArray是VB中用于在网络环境中传递数组的机制,常见于自动化和ADO编程。它通过增加描述符存储数组的维数、长度和元素类型。本文介绍了如何创建、填充、封装SafeArray,以及使用SafeArray处理函数进行数据访问和释放。示例展示了创建、填充和读取SafeArray的步骤,同时列举了常用的相关函数,如SafeArrayCreate、SafeArrayDestroy等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.作用

SafeArray是VB中的数组存储方式。通过SafeArray,可以在VC++和VB间相互调用

在ADO编程中经常使用。

主要目的是用于automation中的数组型参数的传递。因为在网络环境中,数组是不能直接传递的,而必须将其包装成 SafeArray。

实质上SafeArray就是将通常的数组增加一个描述符,说明其维数、长度、边界、元素类型等信息。

SafeArray也并不单独使用,而是将其再包装到VARIANT类型的变量中,然后才作为参数传送出去。

在VARIANT的vt成员的值如果包含VT_ARRAY|...,那么它所封装的就是一个SafeArray,它的parray成员即是指向SafeArray的指针。

SafeArray中元素的类型可以是VARIANT能封装的任何类型,包括VARIANT类型本身。 

2.实例

//(1). 定义变量,如:
int uIsRead = 10;
DOUBLE bVal[] = {0,1,2,3,4,5,6,7,8,9};
//(2). 创建SafeArray描述符:
SAFEARRAY *psa;
SAFEARRAYBOUND rgsabound[1];// = {10,1};
rgsabound[0].cElements =uIsRead;
rgsabound[0].lLbound = 0;
psa = SafeArrayCreate(VT_R8,1,rgsabound);
//(3). 放置数据元素到SafeArray:
for(long index=0;index<=uIsRead;index++)          
{   
    SafeArrayPutElement(psa,&index,&bVal[index ]);
}
//(4). 封装到VARIANT内:   
varChunk->vt = VT_R8;   
varChunk->parray = psa;
//(5)读取SafeArray中的数据的步骤:
DOUBLE buf[10];
for(long ind=0;ind<10;ind++)         
{              
    ::SafeArrayGetElement(pvar.parray,&ind,buf+ind);   
}
double dou = 0;
for (long i = 0;i< 10;i++)
{   
    dou = buf[i];
}

3.常用的SafeArray处理函数

(1)建立SafeArray

SAFEARRAYBOUND   arrbound [1];      //设置维度  
arrbound [0]. lLbound = 0;          //设置第一维的起始下标
arrbound [0]. cElements =  ( long ) arrsize;  //数组的长度

SAFEARRAY* SafeArrayCreate(   //于建立多维普通数组   
    VARTYPE  vt,        //属性类型,一般设置为VT_VARIANT
    unsigned intcDims,  //维度
    SAFEARRRAYBOUND *rgsabound  //传入SAFEARRAYBOUND结构体来设置维度和数组长度
);
          
SAFEARRAY* SafeArrayCreateEx( //用于建立多维自定义类型或接口指针数组  
    VARTYPE vt,  
    unsigned int cDims,  
    SAFEARRRAYBOUND * rgsabound  
    PVOID  pvExtra        //用于创建自定义类型或COM对象的SafeArray数组  
);
        
SAFEARRAY* SafeArrayCreateVector(   //用于建立一维普通数组。
    VARTYPE vt,             //数组类型
    long lLbound,           //数组的最小下标(可以取负数)
    unsigned int cElements  //数组的长度
);

SAFEARRAY* SafeArrayCreateVectorEx(  //用于建立一维自定义类型或接口指针数组。
    VARTYPE vt,
    long lLbound,
    unsigned int cElements,
    LPVOID pvExtra   
);
//上面四个创建SAFEARRAY都返回一个指向SAFEARRAY*的指针,
//通过这个指针可以读写SafeArray中的数据,SafeArray使用完后必须释放。
//数组的最大下标的值是最小下标加上数组长度减一。

vt的取值如下表:

vt值                  类型

VT_UI1             无符号1字节整数(BYTE)数组

VT_UI2             无符号2字节整数(WORD)数组

VT_UI4             无符号4字节整数(DWORD)数组

VT_UINT            无符号整数(UINT)数组

VT_INT             有符号整数(INT)数组

VT_I1                有符号1字节整数数组

VT_I2                有符号2字节整数数组

VT_I4                有符号4字节整数数组

VT_R4               IEEE 4字节浮点数(float)数组

VT_R8               IEEE 8字节浮点数(double)数组

VT_CY              8字节定点数货币值数组

VT_BSTR           VB类型字符串数组

VT_DECIMAL     12字节定点数(大数字)数组

VT_ERROR        标准错误编号数组

VT_BOOL           布尔值数组

VT_DATE           日期型数组

VT_VARIANT      Variant类型数组

SafeArrayCreateVectorEx函数中

pvExtra的含义和vt的取值有关。当vt的取值在上表中的时候,pvExtra的取值没有作用。

当vt取值VT_RECORD时,SafeArrayCreateVectorEx返回一个自定义类型(结构structure或联合union)的数组。这时,pvExtra必须是一个指向IRecordInfo的指针。

当vt取值是VT_UNKNOWN或VT_DISPATCH时。pvExtra是一个指向IID(接口GUID)的指针。在目前的COM规范中,pvExtra只能是IID_IUnknown和IID_IDispatch。并且必须和vt的取值一致。

(2)释放SafeArray数组

HRESULT SafeArrayDestroy(    //释放SafeArray数组
    SAFEARRAY * psa          //创建时取得的指针作为参数
);

(3)访问数据

HRESULT SafeArrayAccessData(     //获取SafeArray的数据指针,并锁定SafeArray数组的数据,在取得了数据指针之后,就可以直接访问SafeArray数组中的数据了
    SAFEARRAY *psa,
    void HUGEP**  ppvData
);
HRESULT SafeArrayUnaccessData(    //释放通过SafeArrayAccessData所取得的指针
    SAFEARRAY * psa
);

(4)确定数组结构

HRESULT SafeArrayGetVartype (       
    SAFEARRAY* pSA,            //pSA是传入的SAFEARRAY指针
    VARTYPE *pVarType          //取得类型,返回“VT_”开头的类型枚举值
);  

(5)取得维数,返回数组的维数

UINT SafeArrayGetDim (
    SAFEARRAY* pSA);   

(6)取得每个维度的属性,返回指定维数(nDim)的上界和下界(nDim从1开始)

HRESULT SafeArrayGetLBound ( //取得nDim维度的上界
    SAFEARRAY* pSA,
    UINT  nDim,              //维度
    long  *pLBound           //接收上界的指针
);                               
HRESULT SafeArrayGetUBound (  //取得nDim维度的下界
    SAFEARRAY* pSA,
    UINT  nDim,
    long  *pUBound
);

(7)取得自定义类型接口,对于自定义结构数组,返回自定义结构类型数据的指针

HRESULT SafeArrayGetRecordInfo (
    SAFEARRAY* pSA,
    IRecordInfo ** ppRecordInfo    //用于存放自定义结构类型数据的指针
);   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值