zoukankan      html  css  js  c++  java
  • SAFEARRAY的使用(转载)

    以下就是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/

  • 相关阅读:
    KafkaOffsetMonitor
    锋利的KATANA
    用grunt搭建自动化的web前端开发环境
    网上书店订单功能的实现
    作用域和控制器
    使用CLK.AspNet.Identity提供以角色为基础的访问控制(RBAC)
    ABP日志管理
    .NET开源项目
    服务总线
    Message解析流程(转)
  • 原文地址:https://www.cnblogs.com/fwycmengsoft/p/3260977.html
Copyright © 2011-2022 走看看