SAFEARRAY的使用(转载)

摘要:
真实数据存储在pvData成员中,SAFEARRAYBOUND结构定义了数组结构的细节。typedefstructtagSAFEARRAYBOUND{unsignedlongcElements;unsignedlonglLbound;}安全绑定;维度在cDims成员中定义。如果我们使用SAFEARRAY来表示这个结构,我们将定义一个包含三个元素的rgsabound数组——一个表示一维。我们将使用的SAFEARRAY只是一个简单的一维字节数组。当我们通过API函数创建数组时,将自动设置SAFEARRAYBOUND。创建一维SAFEARRAY的简单方法是使用SafeArrayCreateVectorAPI函数。在访问SAFEARRAY数据之前,必须调用SafeArrayAccessData。

以下就是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,或者使用一个不同的开始。该数组的详细情况如下所示:

元素cElementsILbound
rgsabound[0]30
rgsabound[1]40
rgsabound[2]50



  关于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(),该功能释放该参数的计数

类型名字描述
byteVT_UI1非负字节
shortVT_I2有符号16位短整型
longVT_I4有符号32位长整型
floatVT_R4一个IEEE 4字节实型数字
doubleVT_R8一个IEEE 8字节实型数字
VARIANT_BOOLVT_BOOL16位布尔 0=false, 0xFFFF=true
SCODEVT_ERROR16位错误码
CYVT_CY16位货币结构
DATEVT_DATE使用双精度数字表示的日期
BSTRVT_BSTRvisual basic风格的字符结构
DECIMALVT_DECIMAL一个十进制的结构
IUnknownVT_UNKNOWN一个COM接口的指针
IDispatchVT_DISPATCHCOM Dispatch接口的指针
SAFEARRAY* VT_ARRAY一个用作传送数组数据的特别结构
VARIANT* VT_VARIANT一个VARIANT结构的指针
void*普通的指针
 VT_BYREF任何类型(除指针外)的指针

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

免责声明:文章转载自《SAFEARRAY的使用(转载)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇win下配置nginx启用TCP端口2375以便外部连接到Docker下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

关于Unity的C#基础学习(四)

一、数组 存放同种类型的一组数据,同类+多个 1.定义 int [] int_set; int_set=new int[10];  //在堆上分配出10个int,int_set是数组的引用变量,指向10个int大小的内存空间。new 类型[容量] 2.访问 数组引用变量名称[索引],int_set[0]=0,int_set[1]=1,int_set[1]=...

FileStream的读取和写入

使用 FileStream 类对文件系统上的文件进行读取、写入、打开和关闭操作,并对其他与文件相关的操作系统句柄进行操作,如管道、标准输入和标准输出。读写操作可以指定为同步或异步操作。FileStream 对输入输出进行缓冲,从而提高性能。  先看代码,后面讲解: using System;using System.Collections.Gener...

C99规范

1. 增加restrict指针    C99中增加了公适用于指针的restrict类型修饰符,它是初始访问指针所指对象的惟一途径,因此只有借助restrict指针表达式才能访问对象。restrict指针指针主要用做函数变元,或者指向由malloc()函数所分配的内存变量。restrict数据类型不改变程序的语义。    如果某个函数定义了两个restr...

Java中各种集合(字符串类)的线程安全性!!!

Java中各种集合(字符串类)的线程安全性!!! 一、概念: 线程安全:就是当多线程访问时,采用了加锁的机制;即当一个线程访问该类的某个数据时,会对这个数据进行保护,其他线程不能对其访问,直到该线程读取完之后,其他线程才可以使用。防止出现数据不一致或者数据被污染的情况。 线程不安全:就是不提供数据访问时的数据保护,多个线程能够同时操作某个数据,从而出现数...

数据结构与算法80道

1. 把二元查找树转变成排序的双向链表 题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。 要求不能创建任何新的结点,只调整指针的指向。    10  /  6 14  / / 4 8 12 16  转换成双向链表 4=6=8=10=12=14=16。   首先我们定义的二元查找树 节点的数据结构如下:  struct BSTreeN...

PHP操作Mysql数据库记录操作函数

简介:这是PHP操作Mysql数据库记录操作函数的详细页面,介绍了和php,有关的知识、技巧、经验,和一些php源码等。 frameborder='0' src='http://biancheng.dnbcw.info/pingjia.php?id=325731' scrolling='no'> 数据库记录操作函数(5个): 1、mysql_fet...