1 SafeArray的作用

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

将SafeArray包装到VARIANT变量中

SAFEARRAY *pSa;

VARIANT v1;

VariantInit(&v1);

v1.vt = VT_I4 | VT_ARRAY; // Array of 4 byte integers

v1.parray = pSa;

2 SafeArray结构体

typedef struct tagSAFEARRAY
{
  unsigned short cDims;//维数   unsigned short fFeatures;// 用来描述数组如何分配和如何被释放的标志   unsigned long cbElements;// 数组元素的大小   unsigned long cLocks;// 一个计数器,用来跟踪该数组被锁定的次数   void * pvData;// 指向数据缓冲的指针   SAFEARRAYBOUND rgsabound[ ];// 描述数组每维的数组结构,该数组的大小是可变的 } 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的初始化方法

方法一 利用SafeArrayAllocDescriptor和SafeArrayAllocData在堆上创建一维数组。 long nData[10]={1,2,3,4,5,6,7,8,9,10};//数据源

SAFEARRAY* pArray=NULL;

HRESULT hr=SafeArrayAllocDescriptor(,&pArray);

HRESULT SafeArrayAllocDescriptor

(

unsigned int cDims,

SAFEARRAY FAR* FAR* ppsaOut

);

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

pArray->rgsabound[].cElements=; pArray->rgsabound[].lLbound=; SafeArrayAllocData(pArray);

long* pData=NULL;

SafeArrayAccessData(pArray,(void**)&pData); long l(),h(); SafeArrayGetLBound(pArray,,&l);//维数索引从1开始

HRESULT SafeArrayGetLBound

(

SAFEARRAY FAR* psa,

unsigned int nDim,

long FAR* plLbound

);

SafeArrayGetUBound(pArray,,&h);

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

SafeArrayUnaccessData(pArray); pData[Idx]=nData[Idx];

方法二 用SafeArrayAllocDescriptor和SafeArrayAllocData在堆上创建二维数组

SAFEARRAY* pArray=NULL;

HRESULT hr=SafeArrayAllocDescriptor(,&pArray)

pArray->rgsabound[].lLbound=;

pArray->rgsabound[].cElements=;

pArray->rgsabound[].lLbound=;

pArray->rgsabound[].cElements=;

pArray->cbElements=sizeof(long);

hr=SafeArrayAllocData(pArray);

赋初值

long Demen[];

for(long i=;i<;++i)

{

for(long j=;j<;++j)

{

Demen[]=i;

}

}

  在SafeArrayPutElement 函数中需要注意的是如何指定所需元素。SafeArrayPutElement 的第二个变量是一指针,它指向数组各维的索引向量。最右边的一维(最低位)放在向量的最前(index[0]);最左边的一维(最低位)放在向量的最后(index【cDims-1]】)。由于在C++中对多维数组的访问正好与此相反,所以需要特别注意这点。

  即用SafeArrayPutElement对二维SAFEARRAY数组使用的时候下标要注意, Demen[1]代表行,Demen[0]代表列。 Demen[0]=j; ong x=i*j; SafeArrayPutElement(pArray,Demen,&x);

访问二维数组

for(long i=;i<;++i)

{

for(long j=;j<;++j)

{

http://9455.net九九文章网

} Demen[]=i; Demen[]=j; long x(); SafeArrayGetElement(pArray,Demen,&x); cout<<"("<<i<<","<<j<<") "<<x<<endl; }

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 = ;

*(pData + ) = ;

*(pData + ) = ;

*(pData + ) = ;

*(pData + ) = ;

*(pData + ) = ;

*(pData + ) =;

*(pData + ) = ;

// Unlock the array.(pData is no longer valid.)

SafeArrayUnaccessData(pSa);

然后进行如下操作

index[] = ;

index[] = ;

SafeArrayGetElement(pSa, index, &NewData);

cout << NewData << endl;

则NewData的值为11

方法四:使用SafeArrayCreate在堆上创建一维数组

SAFEARRAYBOUND Bound[];

Bound[].lLbound=;

Bound[].cElements=; 
SAFEARRAY* pArray=SafeArrayCreate(VT_I4,,Bound);
long* pData=NULL;
HRESULT hr=SafeArrayAccessData(pArray,(void**)&pData);
long Low(),High();
SafeArrayGetLBound(pArray,,&Low);
SafeArrayGetUBound(pArray,,&High);
long Size=High-Low+;
for(long Idx=Low;Idx<Size;++Idx) { } SafeArrayUnaccessData(pArray);
SafeArrayDestroy(pArray);
pData[Idx]=Idx;
cout<<pData[Idx]<<endl;

方法五:使用SafeArrayCreate在堆上创建二维数组

SAFEARRAYBOUND Bound[]; Bound[].lLbound=; Bound[].cElements=; Bound[].lLbound=;

Bound[].cElements=; SAFEARRAY* pArray=SafeArrayCreate(VT_I4,,Bound); long Demen[]; for(long i=;i<;++i) { } for(long j=;j<;++j) { } Demen[]=i; Demen[]=j; long x=i*j; SafeArrayPutElement(pArray,Demen,&x);

//访问二维数组

for(long i=;i<;++i)

{

}

SafeArrayDestroy(pArray); for(long j=;j<;++j) { } Demen[]=i; Demen[]=j; long x(); SafeArrayGetElement(pArray,Demen,&x); cout<<"("<<i<<","<<j<<") "<<x<<endl;

  根据MSDN中SafeArrayAllocDescriptor allows the creation of safe arrays that contain elements with data types other than those provided by After creating an array descriptor using SafeArrayAllocDescriptor, set the element

最新文章

  1. Copy-On-Write容器
  2. ReactiveCocoa源码拆分解析(四)
  3. zabbix特性
  4. BFC学习笔记
  5. 制作DIP Package及DIP焊盘制作,不规则焊盘制作
  6. Swift入门篇-集合
  7. nginx 做负载均衡
  8. [c++][语言语法]stringstream iostream ifstream
  9. iosanimationWithKeyPath
  10. 对OCR文字识别软件的扫描选项怎么设置
  11. 三角形div的原理
  12. java中double四舍五入并设置小数点位数的问题
  13. Docker在云环境中的应用实践初探:优势、局限性与效能评测
  14. 空值排序(oracle和sqlserver)
  15. SNMP_802.1
  16. Phoegap(cordova)开发跨平台app之HelloWorld
  17. runtime - associated(关联)
  18. springmvc的jdbcTemplate 插入 返回主键
  19. 实验:体会Oracle权限/角色赋予的差异
  20. jqGrid数据表格

热门文章

  1. react中事件的使用
  2. react中创建组件以及使用
  3. ue4 renderTexture简单记录
  4. Solr6.7 学习笔记(01) -- 目录结构
  5. [Xcode 实际操作]六、媒体与动画-(7)遍历系统提供的所有滤镜
  6. js中的原型以及原型链
  7. IT兄弟连 JavaWeb教程 使用Servlet实现在页面中显示随机数
  8. IT兄弟连 JavaWeb教程 创建异步请求对象
  9. Elasticsearch内存分配设置详解(转)
  10. thinkPHP5 tablib标签库自定义方法