以下就是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. Bootstrap手动打开隐藏模态框

    开发的时候遇到一个bug,关闭模态框后背景灰色图层依旧还在.原来是用错了隐藏模态框的代码. 正确的调用方式如下: $("#id").modal("show"); ...

  2. unity3d的uGUI基本操作

    uGUI可以免去用户自行创建控件的烦恼,比如button.下面是一个实例: 1.create>UI>Button,如下图所示 新建完成后会出现Canvas和EventSystem,如下图所 ...

  3. node.js express安装问题

    Windows下安装npm和express 1.如果不能在线安装,可以下载npm的zip解压到本地,然后把下面的bin目录加入到path中. 2.搞定npm后,执行了npm install expre ...

  4. python selenium --一些常用方法

    · text  获取该元素的文本 · submit  提交表单 · get_attribute  获得属性值 text   用于获取元素的文本信息 下面把百度首页底部的声明打印输出 #coding=u ...

  5. python 高级语法

    #coding:utf-8 #定义一个装饰器函数 def doc_func(func): #包裹函数(闭包) def warpfunc(): #做一些额外的事情 print "%s call ...

  6. 在intellij中使用checkStyle进行代码规范

    1 编写代码检测规则可以参考阿里和google的规则和checkstyle的官网文档.checkstyle官网地址http://checkstyle.sourceforge.net/ 假设自己的sty ...

  7. MYSQL备份与恢复精华篇

    数据备份原理 数据备份属于数据容灾保护中的内容,所有的数据备份系统设计都基于这五个元素,备份源.备份目标.传输网络.备份引擎和备份策略.用户按照需要制定备份策略,使用定时任务执行备份脚本,使用备份引擎 ...

  8. [docker]docker run指定entrypiont

    指定entrypiont 错误的姿势 docker run -itd -v /tmp/:/tmp/ jdk-ori 'java -jar /tmp/sms.jar' 正确的姿势1 docker run ...

  9. TLS线程局部存储

    0x01 TLS (Thread Local Storage) 为线程单独提供的私有空间 0x02 gcc中的隐式TLS使用方法 隐式TLS __thread int number; 显式TLS pt ...

  10. python学习之urlparse()

    urlparse(url, scheme='', allow_fragments=True) <scheme>://<netloc>/<path>;<para ...