SafeArray用法

萌到你眼炸
591次浏览
2020年08月08日 04:06
最佳经验
本文由作者推荐

2018年日历-服装公司创业计划书


1 SafeArray的作用
使用SafeArray SafeArray是VB 中的数组存储方式。通过SafeArray,可以在
VC++和VB间相互调用。
Safe Array也是Automation中的标准数组存储方式。SAFEARRAY的主要目的是
用于a utomation中的数组型参数的传递。因为在网络环境中,数组是不能
直接传递的,而必须将其包 装成SafeArray。实质上SafeArray就是将通常
的数组增加一个描述符,说明其维数、 长度、边界、元 素类型等信息。
SafeArray也并不单独使用,而是将其再包装到VARIAN T类型的变量中,然
后才作为参数传送出去。在VARIANT的vt成员的 值如果包含VT_ARR AY|...,
那么它所封装的就是一个SafeArray,它的parray成员即是指向Safe Array
的指针。 SafeArray中元素的类型可以是VARIANT能封装的任何类型,包< br>括VARIANT类型本身。
将SafeArray包装到VARIANT变量中
SAFEARRAY *pSa;
VARIANT v1;
VariantInit(&v1);
= VT_I4 | VT_ARRAY; Array of 4 byte integers
= pSa;

2 SafeArray结构体
typedef struct tagSAFEARRAY
{
unsigned short cDims;维数
unsigned short fFeatures; 用来描述数组如何分配和如何被释放的标

unsigned long cbElements; 数组元素的大小
unsigned long cLocks; 一个计数器,用来跟踪该数组被锁定的次数
void * pvData; 指向数据缓冲的指针
SAFEARRAYBOUND rgsabound[ 1 ]; 描述数组每维的数组结构,该数组的


大小是可变的
} SAFEARRAY;
这个结构的成员(cDims,cLocks等)是通过API函数来设置和管理的。真
正的数 据存放在pvData成员中,而SAFEARRAYBOUND结构定义该数组结构的细节。
以下就是 该结构成员的简要描述:
rgsabound成员是一个SAFEARRAYBOUND结构的数组 --每个元素代表SAFEARRAY
的一个维。
typedef struct tagSAFEARRAYBOUND
{
unsigned long cElements; 每维中元素的个数
unsigned long lLbound;
} SAFEARRAYBOUND;
例如C语言中的数组int a[3][4][5]用安全数组表示的时候则
cDims=3 ;cbElements=sizeof(int)
元素 cElements lLbound
rgsabound[0] 3 0
rgsabound[1] 4 0
rgsabound[2] 5 0
3 SafeArray的初始化方法
方法一 利用SafeArrayAllocDe scriptor和SafeArrayAllocData在堆上创建一
维数组。
long nData[10]={1,2,3,4,5,6,7,8,9,10};数据源
SAFEARRAY* pArray=NULL;
HRESULT hr=SafeArrayAllocDescriptor(1,&pArray);
HRESULT SafeArrayAllocDescriptor
(
unsigned int
cDims
,
SAFEARRAY FAR* FAR*
ppsaOut

);


pArray->cbElements=sizeof(nData[0]);



pArray->rgsabound[0].cElements=10;
pArray->rgsabound[0].lLbound=0;
SafeArrayAllocData(pArray);
long* pData=NULL;



SafeArrayAccessData(pArray,(void**)&pData);
long l(0),h(0);
SafeArrayGetLBound(pArray,1,&l);维数索引从1开始
HRESULT SafeArrayGetLBound
(
SAFEARRAY FAR* psa,
unsigned int nDim,
long FAR* plLbound
);
SafeArrayGetUBound(pArray,1,&h);






long Size=h-l+1;
SafeArrayAccessData(pArray,(void**)&pData);
for(long Idx=l;Idx{

}
SafeArrayUnaccessData(pArray);
方法二 用 SafeArrayAllocDescriptor和SafeArrayAllocData在堆上创建二维
数组
SAFEARRAY* pArray=NULL;
HRESULT hr=SafeArrayAllocDescriptor(2,&pArray)
pArray->rgsabound[0].lLbound=0;
pArray->rgsabound[0].cElements=3;
pData[Idx]=nData[Idx];


pArray->rgsabound[1].lLbound=0;
pArray->rgsabound[1].cElements=3;
pArray->cbElements=sizeof(long);
hr=SafeArrayAllocData(pArray);
赋初值
long Demen[2];
for(long i=0;i<3;++i)
{
for(long j=0;j<3;++j)
{
Demen[1]=i;



Demen[0]=j;
ong x=i*j;
SafeArrayPutElement(pArray,Demen,&x);
}
}
在SafeArrayPutElement 函数中需要注意的是如何指定所需元素。
SafeArrayPutElement 的第二个变量是一 指针,它指向数组各维的索引向量。最
右边的一维(最低位)放在向量的最前(index[0]);最 左边的一维(最低位)放在
向量的最后(index【cDims-1]】)。由于在C++中对多维数 组的访问正好与此相
反,所以需要特别注意这点。
即用SafeArrayPutElement对二维SAFEARRAY数组使用的时候下标要注意,
Demen[1]代表行,Demen[0]代表列。
访问二维数组
for(long i=0;i<3;++i)
{
for(long j=0;j<3;++j)


{
Demen[1]=i;







}
Demen[0]=j;
long x(0);
SafeArrayGetElement(pArray,Demen,&x);
cout<<
}
SafeArrayDestroy(pArray);
在 SafeArrayPutElement 与 SafeArrayGetElement 函数的明显的局限 性在于
它们每次只能处理一个数值,在处理大量安全数组的数据时会极大地降低性能。
此时,可 以选择使用函数SafeArrayAccessData 和 SafeArrayUnaccessData。
SafeArrayAccessData 和 SafeArrayUnaccessData 将数组锁定在内存中,并返
回指向该安全数组数据的指针,这样便可以直接访问安全数组中的数据
例如
SafeArray* psa
long * pData;
long * pData;
SafeArrayAccessData(psa, (LPVOID *)&pData);
Set or get any values in the array.
*pData = 4;
*(pData + 1) = 5;
*(pData + 2) = 6;
*(pData + 3) = 7;
*(pData + 4) = 8;
*(pData + 5) = 9;
*(pData + 6) =10;
*(pData + 7) = 11;
Unlock the array.(pData is no longer valid.)
SafeArrayUnaccessData(pSa);
然后进行如下操作


index[0] = 3;
index[1] = 1;
SafeArrayGetElement(pSa, index, &NewData);
cout << NewData << endl; 则NewData的值为11
方法四:使用SafeArrayCreate在堆上创建一维数组
SAFEARRAYBOUND Bound[1];
Bound[0].lLbound=0;















Bound[0].cElements=10;
SAFEARRAY* pArray=SafeArrayCreate(VT_I4,1,Bound);
long* pData=NULL;
HRESULT hr=SafeArrayAccessData(pArray,(void**)&pData);
long Low(0),High(0);
SafeArrayGetLBound(pArray,1,&Low);
SafeArrayGetUBound(pArray,1,&High);
long Size=High-Low+1;
for(long Idx=Low;Idx{


}
SafeArrayUnaccessData(pArray);
SafeArrayDestroy(pArray);
pData[Idx]=Idx;
cout< 方法五:使用SafeArrayCreate在堆上创建二维数组




SAFEARRAYBOUND Bound[2];
Bound[0].lLbound=0;
Bound[0].cElements=3;
Bound[1].lLbound=0;















Bound[1].cElements=3;
SAFEARRAY* pArray=SafeArrayCreate(VT_I4,2,Bound);
long Demen[2];
for(long i=0;i<3;++i)
{







}
for(long j=0;j<3;++j)
{




}
Demen[1]=i;
Demen[0]=j;
long x=i*j;
SafeArrayPutElement(pArray,Demen,&x);
访问二维数组
for(long i=0;i<3;++i)
{








}
SafeArrayDestroy(pArray);
for(long j=0;j<3;++j)







{





}
Demen[1]=i;
Demen[0]=j;
long x(0);
SafeArrayGetElement(pArray,Demen,&x);
cout<<
根据MSDN中SafeArrayAllocDescriptor allows the creation of safe arrays
that contain elements with data types other than those provided by
SafeArrayCreate. After creating an array descriptor using


SafeArrayAllocDescriptor, set the element size in the array descriptor,
an call SafeArrayAllocData to allocate memory for the array elements.(这
主要是因为在SafeArrayCreate函数中有一个Va riant参数限定了data types)
访问SAFEARRAY:
方法一:使用SafeArrayAccessData方法
这种方法可以参见创建SAFEARRAY之方法一
请注意,访问完后要调用SafeArr ayUnaccessData方法,并且调用
SafeArrayDestroy销毁数组,这种方式 通常用于访问一位数组
方法二:使用SafeArrayGetElement和SafeArrayPutElement
这种方法可以参见创建SAFEARRAY之方法五,这种方式在访问多维数组的时候很
有用





无锡中考-师说原文及翻译


读雷锋的故事有感-会计从业资格考试试题及答案下载


小学生植树节手抄报-爱来过


党务工作-生日祝福语短信


诚实的名言警句-全国文科二本大学排名


培训方案范文-上外贤达教务系统


推广普通话的手抄报-一二九运动


个人党性分析材料-河北省学业水平考试成绩查询