SAFEARRAY

  SAFEARRAY的主要目的是用于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)))

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

  }

  ::SafeArrayUnaccessData(psa);

  varChunk.vt = VT_ARRAY|VT_UI1;

  varChunk.parray = psa;

  这种方法读写SafeArray都可以,它直接操纵SafeArray的数据缓冲区,比用SafeArrayGetElement和 SafeArrayPutElement速度快。特别适合于读取数据。但用完之后不要忘了调用::SafeArrayUnaccessData (psa),否则会出错的。

  如果SafeArray中存的是BSTR的二维数组,则代码如下:

  if(varChunk.vt = VT_ARRAY | VT_BSTR)

  {

  BSTR* buf;

  long LBound; // 数组下界

  long UBound; // 数组上界

  SafeArrayAccessData(varChunk.parray, (void **)&buf);

  SafeArrayGetLBound(varChunk.parray, 1, &LBound);

  SafeArrayGetUBound(varChunk.parray, 1, &UBound);

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

  {

  CString str(buf);

  MessageBox(str);

  }

  SafeArrayUnaccessData(varChunk.parray);

  }

------------------------------------------------------------------------------------------------------------------------------

COleSafeArray

COleSafeArray类是用于处理任意类型和维数的数组的类。COleSafeArray是从OLE VARIANT结构派生而来的。OLE SAFEARRAY成员函数在可以通过COleSafeArray来访问,就象是特别为一维的字节数组所设计的一个成员函数集。

#include

请参阅:COleVariant, CRecordset, CDatabase

COleSafeArray类成员

构造 COleSafeArray 构造一个COleSafeArray对象

操作

Attach 给COleSafeArray对象以存在的VARIANT数组的控制

Clear 释放基VARIANT中的所有数据

Detach 将VARIANT数组从COleSafeArray对象中分离出来(这将使数据不会被释放)

Win32 API 包装 AccessData 获取一个指向数组数据的指针

AllocData 为数组分配内存

AllocDescriptor 为安全数组描述符分配内存

Copy 创建一个已存在的数组的拷贝

Create 创建一个安全数组

Destroy 销毁一个已经存在的数组

DestroyData 销毁一个安全数组中的数据

DestroyDescriptor 销毁一个安全数组的描述符

GetDim 返回数组的维数

GetElement 获取安全数组中的一个单一元素

GetElemSize 返回安全数组中一个元素的按字节表示的大小

GetLBound 返回一个安全数组任一维的下界

GetUBound 返回一个安全数组任一维的上界

Lock 增加一个数组的加锁计数,并将一个指向数组数据的指针放到数组描述符中

PtrOfIndex 返回一个指向被索引的元素的指针

PutElement 将一个单一的元素放入数组中

Redim 改变一个安全数组的最不重要(最右边)的边界

UnaccessData 减小一个数组的加锁计数,并使由AccessData获得的指针无效

Unlock 减小一个数组的加锁以使它能被释放或改变大小

一维数组操作 CreateOneDim 创建一个一维的COleSafeArray对象

GetOneDimSize 返回一个一维的COleSafeArray对象中的元素个数

ResizeOneDim 改变一个一维的COleSafeArray对象中的元素个数

操作 operator = 将一些值(包括SAFEARRAY,VARIANT,COleVariant,或COleSafeArray对象)拷贝到COleSafeArray对象中

operator == 比较两个不同的数组(SAFEARRAY,VARIANT,ColeVariant,或COleSafeArray对象)

operator

COleSafeArray::COleSafeArray

COleSafeArray();

COleSafeArray( const SAFEARRAY& saSrc, VARTYPE vtSrc );

COleSafeArray( LPCSAFEARRAY psaSrc, VARTYPE vtSrc );

COleSafeArray( const COleSafeArray& saSrc );

COleSafeArray( const VARIANT& varSrc );

COleSafeArray( LPCVARIANT pSrc );

COleSafeArray( const COleVariant& varSrc );

参数: saSrc 要被拷贝到新的COleSafeArray对象中去的已经存在的COleSafeArray对象或SAFEARRAY。

vtSrc 新的COleSafeArray对象的VARTYPE。

psaSrc 一个指向要被拷贝到新的COleSafeArray对象中去的SAFEARRAY的指针。

varSrc 要被拷贝到新的COleSafeArray对象中去的已经存在的VARIANT或者COleVariant。

pSrc 一个指向要被拷贝到新的COleSafeArray对象中去的VARIANT对象的指针。

说明:

所有这些构造函数都创建一个新的COleSafeArray对象。如果没有参数,则创建的是一个空的COleSafeArray对象(VT_EMPTY)。如果COleSafeArray是从另一个数组拷贝来的,并且这个数组的VARTYPE并不是完全确定的(一个COleSafeArray,COleVariant,或者VARIANT),则源数组中的VARTYPE被保留,并且不需要说明。如果COleSafeArray是从另一个数组拷贝而来,并且该数组的VARTYPE是不知道的,则VARTYPE必须用vtSrc参数来指定。

如果出错,则函数抛出一个CMemoryException或COleException。

请参阅:VariantCopy

-------------------------------------------------------------------------------------------------------------------------------

VARTYPE

An enumeration type used in VARIANT, TYPEDESC, OLE property sets, and safe arrays.

The enumeration constants listed in the following VARENUM section are valid in the vt field of a VARIANT structure.

typedef unsigned short VARTYPE;

enum VARENUM{

VT_EMPTY     = 0,     // Not specified.

VT_NULL      = 1,     // Null.

VT_I2        = 2,     // 2-byte signed int.

VT_I4        = 3,     // 4-byte signed int.

VT_R4        = 4,     // 4-byte real.

VT_R8        = 5,     // 8-byte real.

VT_CY        = 6,     // Currency.

VT_DATE      = 7,     // Date.

VT_BSTR      = 8,     // Binary string.

VT_DISPATCH = 9,     // IDispatch

VT_ERROR     = 10,    // Scodes.

VT_BOOL      = 11,    // Boolean; True=-1, False=0.

VT_VARIANT   = 12,    // VARIANT FAR*.

VT_UNKNOWN   = 13,    // IUnknown FAR*.

VT_UI1       = 17,    // Unsigned char.

// Other constants that are not valid in VARIANTs omitted here.

};

VT_RESERVED = (int) 0x8000

// By reference, a pointer to the data is passed.

VT_BYREF     = (int) 0x4000

VT_ARRAY     = (int) 0x2000   // A safe array of the data is passed.

   

VC++ COleSafeArray VARIANT的使用相关推荐

  1. VC++ 串口 VARIANT型变量转换为ColeSafeArray型变量老提示错误

    VARIANT variant_inp; COleSafeArray safearray_inp; variant_inp=m_CMscomm.get_Input(); safearray_inp=v ...

  2. COleSafeArray VC

    COleSafeArray VC  COleSafeArray: COleSafeArray类是用于处理任意类型和维数的数组的类.COleSafeArray是从OLE VARIANT结构派生而来的.O ...

  3. SAP独门神器之VC变式配置,硬核整理版重磅推出!

    1 VC基本概念及应用场景 VC是Variant Configuration,是依据客户需求做选择配置,完成后通过Super BOM及Super Routing结合相关性找到找到所需要物料及工序,来简 ...

  4. 转:VC++常用数据类型转换

      留着方便自查 VC++数据类型转换 int i = 100; long l = 2001; float f=300.2; double d=12345.119; char username[]=& ...

  5. Variant类型在各语言中的参数传递

    几年前我用VB开发了一个西门子PPI通信控件,由于VB开发的控件是标准的COM组件,所以想当然的认为VC.C#.Delphi等开发语言可以非常容易的使用. 前段时间由于该控件基于微软的MSCOMM控件 ...

  6. VC++类型转换大全

    Cpp代码   int i = 100; long l = 2001; float f=300.2; double d=12345.119; char username[]="程佩君&quo ...

  7. VC++常用数据类型及其操作详解 [

    一.VC常用数据类型列表 二.常用数据类型转化 2.1数学类型变量与字符串相互转换 2.2 CString及string,char *与其他数据类型的转换和操作 ●CString,string,cha ...

  8. VC++数据类型转换小结

    说明:本文纯粹是总结一下有关类型转换的贴子, 本人并未对所有方法都做测试,仅仅是为了给大家一个参考. int i = 100; long l = 2001; float f=300.2; double ...

  9. VC++常用数据类型及其操作详解(非常经典,共同分享)

    友情提示: 为了方便你更好的学习和阅读,也更好的体现尊重原创作者的劳动成果,请您直接查看转载原本链接: http://snailflying.blog.hexun.com/8219350_d.html ...

最新文章

  1. 文巾解题 977. 有序数组的平方
  2. 围猎“下沉市场”,争抢「小镇青年」,尚美如何突围?
  3. boost::bron_kerbosch_all_cliques用法的测试程序
  4. PGM中置信传递、和—积算法
  5. opencv问题解析
  6. 费诺编码的gui页面设计_GUI设计和UI设计有什么区别?
  7. 如何快速成为C++工程师?
  8. Android源码分析:Activity启动流程
  9. 直方图、正态分布图与SPC图
  10. JS方式获取浏览器版本
  11. 银行计算机岗位招聘简历,银行校园招聘网申,机器和HR如何筛选简历?
  12. 台式计算机技术参数响应表,详细技术参数响应表介绍.doc
  13. 主板usb接口全部失灵_主板usb接口全部失灵
  14. canvas 将两张图片叠加
  15. MPLS LDP原理
  16. 杰理之上下文件夹播放上文件夹从最后一首播放【篇】
  17. Word 文字处理学习笔记
  18. TensorRT加速
  19. 西邮ctf2020 web之文件包含解析
  20. php大会2018,2018 INFORMS国际大会

热门文章

  1. 03-12 Android 混合页面测试
  2. 数据库-子查询概念和分类
  3. 关于计算机网络与应用的相关片,网络技术与应用作业.doc
  4. fpga初始化错误_FPGA的ROM初始化问题讨论
  5. web前端是什么?如何能成为一名合格的前端开发工程师?
  6. python二维数据读取对齐_python代码要严格对齐
  7. latch.await java有什么作用,Android系统。 Countdownlatch.await不起作用
  8. 一阶广义差分模型_贵州茅台(600519)股价预测 (ARIMA模型)
  9. python动态获取cookie_看到很多人求助python 我也求助一下如何写cookie的获取和登录吧...
  10. python正则替换查询_使用Python中的正则表达式进行搜索和替换