以下就是SAFEARRAY的Win32定义:

  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结构定义该数组结构的细节。以下就是该结构成员的简要描述:

成员 描述
cDims 数组的维数
fFeatures 用来描述数组如何分配和如何被释放的标志
cbElements 数组元素的大小
cLocks 一个计数器,用来跟踪该数组被锁定的次数
pvData 指向数据缓冲的指针
rgsabound 描述数组每维的数组结构,该数组的大小是可变的

  rgsabound是一个有趣的成员,它的结构不太直观。它是数据范围的数组。该数组的大小依safe array维数的不同而有所区别。rgsabound成员是一个SAFEARRAYBOUND结构的数组--每个元素代表SAFEARRAY的一个维。

  typedef struct tagSAFEARRAYBOUND

   {

    unsigned long cElements;

    unsigned long lLbound;

   } SAFEARRAYBOUND;

  维数被定义在cDims成员中。例如,一个'C'类数组的维数可以是[3][4][5]-一个三维的数组。如果我们使用一个SAFEARRAY来表示这个结构,我们定义一个有三个元素的rgsabound数组--一个代表一维。

  cDims = 3;
    ...
  SAFEARRAYBOUND rgsabound[ 3 ];

  rgsabound[0]元素定义第一维。在这个例子中ILBOUND元素为0,是数组的下界。cElements成员的值等于三。数组的第二维([4])可以被rgsabound结构的第二个元素定义。下界也可以是0,元素的个数是4,第三维也是这样。要注意,由于这是一个"C"数组,因此由0 开始,对于其它语言,例如Visual Basic,或者使用一个不同的开始。该数组的详细情况如下所示:

元素 cElements ILbound
rgsabound[0] 3 0
rgsabound[1] 4 0
rgsabound[2] 5 0

  关于SAFEARRAYBOUND结构其实还有很多没说的。我们将要使用的SAFEARRAY只是一个简单的单维字节数组。我们通过API函数创建数组的时候,SAFEARRAYBOUND将会被自动设置。只有在你需要使用复杂的多维数组的时候,你才需要操作这个结构。

  还有一个名字为cLocks的成员变量。很明显,它与时间没有任何的关系--它是一个锁的计数器。该参数是用来控制访问数组数据的。在你访问它之前,你必须锁定数据。通过跟踪该计数器,系统可以在不需要该数组时安全地删除它。

创建SAFEARRAY

  创建一个单维SAFEARRAY的简单方法是通过使用SafeArrayCreateVector API函数。该函数可分配一个特定大小的连续内存块。

  SAFEARRAY *psa;

  file:// create a safe array to store the stream data

  file:// llen is the number of bytes in the array.

  psa = SafeArrayCreateVector( VT_UI1, 0, llen );

  SafeArrayCreateVector API创建一个SAFEARRAY,并且返回一个指向它的指针。首个参数用来定义数组的类型--它可以是任何有效的变量数据类型。为了传送一个串行化的对象,我们将使用最基本的类型--一个非负的字节数组。VT--UI1代表非负整形的变量类型,1个字节。

  常数'0'定义数组的下界;在C++中,通常为0。最后的参数llen定义数组元素的个数。在我们的例子中,这与我们将要传送对象的字节数是一样的。我们还没有提数组大小(llen)是怎样来的,这将在我们重新考查串行化时提及。

  在你访问SAFEARRAY数据之前,你必须调用SafeArrayAccessData。该函数锁定数据并且返回一个指针。在这里,锁定数组意味着增加该数组的内部计数器(cLocks)。

  file:// define a pointer to a byte array

  unsigned char *pData = NULL;

  SafeArrayAccessData( psa, (void**)&pData );

   ... use the safe array

  SafeArrayUnaccessData(psa);

  相应用来释放数据的函数是SafeArrayUnaccessData(),该功能释放该参数的计数

类型 名字 描述
byte VT_UI1 非负字节
short VT_I2 有符号16位短整型
long VT_I4 有符号32位长整型
float VT_R4 一个IEEE 4字节实型数字
double VT_R8 一个IEEE 8字节实型数字
VARIANT_BOOL VT_BOOL 16位布尔 0=false, 0xFFFF=true
SCODE VT_ERROR 16位错误码
CY VT_CY 16位货币结构
DATE VT_DATE 使用双精度数字表示的日期
BSTR VT_BSTR visual basic风格的字符结构
DECIMAL VT_DECIMAL 一个十进制的结构
IUnknown VT_UNKNOWN 一个COM接口的指针
IDispatch VT_DISPATCH COM Dispatch接口的指针
SAFEARRAY * VT_ARRAY 一个用作传送数组数据的特别结构
VARIANT * VT_VARIANT 一个VARIANT结构的指针
void * 普通的指针
  VT_BYREF 任何类型(除指针外)的指针

转载自:http://xjchilli.blog.163.com/blog/static/453477392010811322173/

SAFEARRAY的使用(转载)的更多相关文章

  1. c#winform使用WebBrowser 大全[超长文转载]

    1.主要用途:使用户可以在窗体中导航网页. 2.注意:WebBrowser 控件会占用大量资源.使用完该控件后一定要调用 Dispose 方法,以便确保及时释放所有资源.必须在附加事件的同一线程上调用 ...

  2. Crystal Clear Applied: The Seven Properties of Running an Agile Project (转载)

    作者Alistair Cockburn, Crystal Clear的7个成功要素,写得挺好. 敏捷方法的关注点,大家可以参考,太激动所以转载了. 原文:http://www.informit.com ...

  3. RTP与RTCP协议介绍(转载)

    RTSP发起/终结流媒体.RTP传输流媒体数据 .RTCP对RTP进行控制,同步.RTP中没有连接的概念,本身并不能为按序传输数据包提供可靠的保证,也不提供流量控制和拥塞控制,这些都由RTCP来负责完 ...

  4. 《Walking the callstack(转载)》

    本文转载自:https://www.codeproject.com/articles/11132/walking-the-callstack Download demo project with so ...

  5. [转载]MVVM模式原理分析及实践

    没有找到很好的MVVM模式介绍文章,简单找了一篇,分享一下.MVVM实现了UI\UE设计师(Expression Blend 4设计界面)和软件工程师的合理分工,在SilverLight.WPF.Wi ...

  6. [转载]:STM32为什么必须先配置时钟再配置GPIO

    转载来源 :http://blog.csdn.net/fushiqianxun/article/details/7926442 [原创]:我来添两句,就是很多同学(包括我)之前搞低端单片机,到了stm ...

  7. [转载]从MyEclipse到IntelliJ IDEA-让你摆脱鼠标,全键盘操作

    从MyEclipse转战到IntelliJ IDEA的经历 注转载址:http://blog.csdn.net/luoweifu/article/details/13985835 我一个朋友写了一篇“ ...

  8. TCP同步与异步,长连接与短连接【转载】

    原文地址:TCP同步与异步,长连接与短连接作者:1984346023 [转载说明:http://zjj1211.blog.51cto.com/1812544/373896   这是今天看到的一篇讲到T ...

  9. 在CentOS 7/6.5/6.4 中安装Java JDK 8(转载)

    转载在CentOS 7/6.5/6.4 中安装Java JDK 8 首先,在你的服务器上运行一下更新. yum update 然后,在您的系统上搜索,任何版本的已安装的JDK组件. rpm -qa | ...

随机推荐

  1. java基础讲解13-----集合

    一:集合介绍 import java.util.ArrayList;import java.util.Collection;import java.util.Iterator; public clas ...

  2. windows Service 2012 系统时间格式带中文

    C# 获取DataTime.Now   显示     2019年4月23日 下午 10:03:00 导致转换格式失败, 因为 源码中写的是   DataTime.Now.ToString();   输 ...

  3. docker运行环境安装-centos(一)

    在这里我们使用的是docker的社区版Docker CE,针对的是未安装docker的新的主机,如果安装过docker的早期版本,先卸载它们及关联的依赖资源,安装的版本为docker 18.03. 1 ...

  4. swift -变量的定义与使用

    使⽤用let来声明常量,使⽤用var来声明变量. ⼀一个常量的值在编译时并不须要获取,可是你仅仅能为它赋值⼀一次.也就是说你能够⽤用常量来表⽰示这样⼀一个值:你仅仅须要决定⼀一次,可是须要使⽤用非常多 ...

  5. Atitit.导出excel功能的设计 与解决方案

    Atitit.导出excel功能的设计 与解决方案 1.1. 项目起源于背景1 1.2. Js  jquery方案(推荐)jquery.table2excel1 1.3. 服务器方案2 1.4. 详细 ...

  6. vivado笔记

    Vivado主界面 Vivado套件,相当于把ISE.ISim.XPS.PlanAhead.ChipScope和iMPACT等多个独立的套件集合在一个Vivado设计环境中,在这个集合的设计流程下,不 ...

  7. Xilinx资源优化问题

    资源优化问题:Xilinx ise 出现资源不够的问题(ERROR:Cpld:868 - Cannot fit the design into any of the specified devices ...

  8. Makefile 自动变量之 $(@D),$(@F)

    参考:http://www.gnu.org/software/make/manual/make.html '$(@D)'The directory part of the file name of t ...

  9. python学习之logging模块

    Logger.setLevel(level) 设置记录器的级别为level.低于该级别的信息将被忽略. 记录器默认级别为NOTSET.如果记录器是根记录器,则默认将记录所有信息: 如果是一个非根记录器 ...

  10. sqoop从hdfs 中导出数据到mysql

    bin/sqoop export \ --connect "jdbc:mysql://mini1:3306/study?useUnicode=true&characterEncodi ...