zoukankan      html  css  js  c++  java
  • C++使用VARIANT实现二维数组的操作

    VARIANT变量是COM组件之间互相通信的重要的参数变量之一,它可以容纳多种不同的类型,如short、long、double等,包括各类指针和数组。组件之间的互相调用是比较耗时的,尤其带当组件位于不同进程中时,因此,减少传递次数是提高效率的一种有效方法。其中,Excel表格的操作就可能涉及到大量数据,一次传递一个二维数组是提高对Excel表的操作效率。下面以两种不同方式来实现VARIANT二维数组的操作。

    1、使用SAFEARRAY实现二维数组

    SAFEARRAY安全数组可以实现多维数组,SAFEARRAY实现的步骤可以大致分为三步。

    (1)创建SAFEARRAY安全数组,包括设置数组元素的类型、数据的维数,大小等。

    (2)对SAFEARRAY数组赋值,既可通过SafeArrayPutElement函数逐个元素进行负责,也可通过指针来获得SAFEARRAY的数据地址,然后对指针指向的值进行赋值操作。其中,如果SAFEARRAY中的数组时多维数组,即可以把多维数组转换为一维数组,也可以通过获得指向数组的指针方式来操作数组中的元素。

    (3)使用VARIANT变量把SAFEARRAY进行包装。

    使用SAFEARRAR实现二维数组的源代码如下:

    复制代码
      VARTYPE vt = VT_I4; /*数组元素的类型,long*/
      SAFEARRAYBOUND sab[
    2]; /*用于定义数组的维数和下标的起始值*/
      sab[
    0].cElements =2;
      sab[
    0].lLbound =0;
      sab[
    1].cElements =2;
      sab[
    1].lLbound =0;
      /*创建一个2*2的类型为long的二维数组*/
      SAFEARRAY
    * psa = SafeArrayCreate(vt, sizeof(sab)/sizeof(SAFEARRAYBOUND), sab);
      if (NULL == psa)
      {
      
    throw;
      }


      /*通过指向数组的指针来对二维数组的元素进行间接赋值*/
      long (*pArray)[2= NULL;
      HRESULT hRet 
    = SafeArrayAccessData(psa, (void **)&pArray);
      if (FAILED(hRet))
      {
        throw;
      }
      memset(pArray, 
    02*2*sizeof(long));
      /*释放指向数组的指针*/
      SafeArrayUnaccessData(psa);
      pArray 
    = NULL;

      /*对二维数组的元素进行逐个赋值*/
      long index[2= {00};
      long lFirstLBound = 0;
      long lFirstUBound = 0;
      long lSecondLBound = 0;
      long lSecondUBound = 0;
      SafeArrayGetLBound(psa, 
    1&lFirstLBound);
      SafeArrayGetUBound(psa, 
    1&lFirstUBound);
      SafeArrayGetLBound(psa, 
    2&lSecondLBound);
      SafeArrayGetUBound(psa, 
    2&lSecondUBound);
      for (long i = lFirstLBound; i <= lFirstUBound; i++)
      {
        index[
    0= i;
        for (long j = lSecondLBound; j <= lSecondUBound; j++)
        {
          index[
    1= j;
          long lElement = i * sab[1].cElements + j; 
          HRESULT hRet 
    = SafeArrayPutElement(psa, index, &lElement);
          if (FAILED(hRet))
          {
             throw;
          }
         }
      }

      /*把SAFEARRAY转换为VARIANT*/
      VARIANT var;
      var.vt 
    = VT_ARRAY | vt; /*vt必须和psa的数据类型保持一致*/
      var.parray 
    = psa;
      SafeArrayDestroy(psa);
      psa 
    = NULL;

    复制代码

    2、使用COleSafeArray实现二维数组

    COleSafeArray继承于VARIANT,是MFC的自动化类,因此,只有在使用MFC类库时才能使用该类。COleSafeArray封装操作相关的函数,可通过MSDN查询该类的成员函数来了解与安全数组相关的函数。COleSafeArray还可以直接转换为VARIANT。因此,相对于SAFEARRAY,COleSafeArray的使用更方便。COleSafeArray和SAFEARRAY之间的关系就是MFC类库和Win32 SDK的关系,使用步骤类似。

    使用COleSafeArray实现二维数组的源代码如下所示:

    复制代码
        VARTYPE vt = VT_I4; /*数组元素的类型,long*/
    SAFEARRAYBOUND sab[
    2]; /*用于定义数组的维数和下标的起始值*/
    sab[
    0].cElements =2;
    sab[
    0].lLbound =0;
    sab[
    1].cElements =2;
    sab[
    1].lLbound =0;

    COleSafeArray olesa;
    olesa.Create(vt,
    sizeof(sab)/sizeof(SAFEARRAYBOUND), sab);

      /*通过指向数组的指针来对二维数组的元素进行间接赋值*/
      long (*pArray)[2= NULL;
      olesa.AccessData((
    void **)&pArray);
      memset(pArray, 
    02*2*sizeof(long));
      /*释放指向数组的指针*/
      olesa.UnaccessData();
      pArray 
    = NULL;


      /*对二维数组的元素进行逐个赋值*/
      long index[2= {00};
      long lFirstLBound = 0;
      long lFirstUBound = 0;
      long lSecondLBound = 0;
      long lSecondUBound = 0;
      olesa.GetLBound(
    1&lFirstLBound);
      olesa.GetUBound(
    1&lFirstUBound);
      olesa.GetLBound(
    2&lSecondLBound);
      olesa.GetUBound(
    2&lSecondUBound);
      for (long i = lFirstLBound; i <= lFirstUBound; i++)
      {
        index[
    0= i;
        for (long j = lSecondLBound; j <= lSecondUBound; j++)
        {
          index[
    1= j;
          long lElement = i * sab[1].cElements + j; 
          olesa.PutElement(index, 
    &lElement);
        }
      }



    /*把COleSafeArray变量转换为VARIANT*/
    VARIANT var
    = (VARIANT)olesa;
    复制代码

     参考资料

    http://blog.sina.com.cn/s/blog_74f586a50100rv6t.html
    http://hfp0601.blog.163.com/blog/static/228483522011031104718762/

  • 相关阅读:
    在 easyui中获取form表单中所有提交的数据 拼接到table列表中
    easyui中清空table列表中数据
    easyui中加载table列表数据 第一次有数据第二次没有数据问题
    jsp中将一个jsp引入另一个jsp指定位置
    maven项目修改名称后,打包名称和现在名称不一致
    动态sql
    日期转化类 ,日期格式处理
    easyui中权限分配和添加 前后端代码
    ubuntu14.04下播放器SMplayer的安装
    C++的 new 和 detele
  • 原文地址:https://www.cnblogs.com/host-2008/p/3673582.html
Copyright © 2011-2022 走看看