SAFEARRAY基本用法详解

来源:互联网 发布:php放到path 环境变量 编辑:程序博客网 时间:2024/06/06 07:03

使用ADO技术连接数据库时,经常要用到SAFEARRAY传递参数(我遇到的是向数据库添加数据时,有一种方法要用到SAFEARRAY)。我也是花了几天,断断续续的在看SAFEARRAY,刚开始的时候也是非常迷糊,不知道这是什么,只有照着书把代码敲到了电脑上,第二次还是不明白这些代码都做了什么,变量和参数都什么意思。今天下午在网上,书上包括直接在VS上看变量的定义,总算大概了解了点,基本掌握了一维数组的用法,下面是我自己对SAFEARRAY的理解,不当之处,还望之处,不懂之处,欢迎讨论。

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

一、要打包的数据和需要定义的变量

_variant_t vValue[4];vValue[0] = _bstr_t("CSDN");vValue[1] = _bstr_t("心中有道");vValue[2] = _bstr_t("博客");vValue[3] = _bstr_t("SAFEARRAY");SAFEARRAY *psaValue;SAFEARRAYBOUND rgsaBound[1];VARIANT vsaValue;


二、各变量的意义

SAFEARRAY就是所谓的安全数组,psaValue是一个指向SAFEARRAY的指针,在VC中,SAFEARRAYBOUND的定义如下:

typedef struct tagSAFEARRAYBOUND{ULONG cElements;LONG lLbound;} SAFEARRAYBOUND;typedef struct tagSAFEARRAYBOUND *LPSAFEARRAYBOUND;


SAFEARRAYBOUND是一个结构体,里面有两个变量,ULONG cElements表示的是元素的数目(更准确的说是在本维中的数目);LONG lLbound表示的是一个逻辑起点序号,实际访问内存的时候,安全数组会将程序指定的序号减去lLbound,比如你将其设置为10000,a[10000]这相当于A[0],a[999]数组越界,所以在没有特殊要求的情况下,lLbound一般为0。还有一点,定义的时候是SAFEARRAYBOUND rgsaBound[1], 这点要解释一下,rgsaBound[1]表示的是一位数组,二维数组要定义为rgsaBound[2],这里主要讲解一位数组,更高维数大家可以去搜一下,和一维的相似。

VARIANT vsaValue,这个就是最终要的得到的变量了,可以把这个变量作为参数传出去。

三、实现代码及函数、参数意义

psaValue = SafeArrayCreate(VT_VARIANT, 1, rgsaBound);for (long i = 0; i < 4; i++){SafeArrayPutElement(psaValue, &i, &vValue[i]);}vsaValue.vt = VT_ARRAY | VT_VARIANT;V_ARRAY(&vsaValue) = psaValue;



代码不是很多,甚至很少,但是代码要一句一句的讲下

1、创建SAFEARRAY

psaValue = SafeArrayCreate(VT_VARIANT, 1, rgsaBound);



第一个参数VT_VARIANT表示数组的类型,第二个参数表示创建数组的维数,本例中是一维,第三个参数是对这个数组各个维度的描述。
SafeArrayCreate()就是创建SAFEARRAY的函数,准确的说是在堆中创建了一个SAFEARRAY,也就是说在这个函数里面,调用了new或者malloc()之类的申请了一个空间(我有个疑问是这个空间是否需要自己用delete释放,C++学的不好,对这不太清楚)。还有一些函数是在栈(也就是临时变量)中实现了SAFEARRAY,这个函数我还没了解,就不在这讨论了。

2、放置元素到数组中

for (long i = 0; i < 4; i++){SafeArrayPutElement(psaValue, &i, &vValue[i]);}



严格的来讲,这段代码只能在一维数组中使用,当然,如果一维数组够用的话,这个方法也挺方便的,下面这段代码是比较准确的:

long demen[1];for (int i = 0; i < 4; i++){demen[i] = i;SafeArrayPutElement(psaValue, demen, &vValue[i]);}//如果是二维数组,应该这样/*long demen[2];for (int i = 1; i < 4; i++)//假设是一个4*4的二维数组{for (int j = 1; j < 4; j++){demen[0] = i;demen[1] = j;SafeArrayPutElement(psaValue, demen, &x);}}*/


第一个参数是指向SAFEARRAY的指针;第二个参数是long型数组指针,表示SAFEARRAY元素的下标,即唯一确定一个SAFEARRAY元素;第三个参数就是要放置的那个值得指针了。

3、指明vsaValue存放值得类型

vsaValue.vt = VT_ARRAY | VT_VARIANT;


在VARIANT的vt成员的值如果包含VT_ARRAY,那么它所封装的就是一个SAFEARRAY,它的parray成员即是指向SAFEARRAY的指针。
VT_ARRAY说明vsaValue封装的是一个SAFEARRAY,VT_VARIANT说明SAFEARRAY的元素是VARIANT类型。

4、完成封装

V_ARRAY(&vsaValue) = psaValue; //等价于vsaValue.parray = psaValue



V_ARRAY()是VC中的一个宏,定义如下:

#define V_ARRAY(X)       V_UNION(X, parray)#define V_UNION(X, Y)   ((X)->Y)


到这也算差不多了,第一次在CSDN上写一个讲解,纪念一下大笑
1 0
原创粉丝点击