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, 0, 2*2*sizeof(long));
  /*释放指向数组的指针*/
  SafeArrayUnaccessData(psa);
  pArray = NULL;

  /*对二维数组的元素进行逐个赋值*/
  long index[2] = {0, 0};
  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, 0, 2*2*sizeof(long));
  /*释放指向数组的指针*/
  olesa.UnaccessData();
  pArray = NULL;

  /*对二维数组的元素进行逐个赋值*/
  long index[2] = {0, 0};
  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/

C++使用VARIANT实现二维数组的操作相关推荐

  1. C++使用VARIANT实现二维数组的操作、怎么使用COleSafeArray实现二维数组将字符串写入excel

    配合OLED_V2的excel操作 C++使用VARIANT实现二维数组的操作 VARIANT变量是COM组件之间互相通信的重要的参数变量之一,它可以容纳多种不同的类型,如short.long.dou ...

  2. C# 指定格式的字符串截成一维数组(二维数组)的操作类

    指定格式的字符串截成一维数组(二维数组)的操作类 做项目时经常会遇到将"1,3,a,b,d"截成一维数组或将"1,a;2,b;3,c;4,d"截成二维数组.虽然 ...

  3. C++中使用new和delete运算符实现二维数组的操作

    线上代码,解析在下方 List item #include <iostream> #include <string> #include <cstring> #inc ...

  4. php 读取mysql 二维数组_PHP操作 二维数组模拟mysql函数

    PHP操作 二维数组模拟mysql函数 public function monimysqltest(){ $testarray=array( array('ss'=>'1','dd'=>' ...

  5. Python——二维数组遍历操作

    一.遍历数组(操作Value) 1.使用二维列表遍历二维数组 python 创建List二维列表 lists = [[] for i in range(3)] # 创建的是多行三列的二维列表 for ...

  6. nRF51800 蓝牙学习 进程记录 2:关于二维数组 执念执战

    前天在玩OLED时想完成一直想弄得一个东西,就是简单的单片机游戏.因为STM32和nRF51822的内存足够,所以就用缓存数组的方法来显示图像(我也不知道术语是啥,反正就是在内存中建立一个128X64 ...

  7. C/C++函数传递二维数组

    目录 函数参数传递二维数组的问题 解决方案 1.传递第二维和更高维的大小 2.根据数组的存储原理把二位数组当作一维数组来操作(降维处理) 函数参数传递二维数组的问题 将二维数组当作参数的时候,必须指明 ...

  8. python二维数组的创建和操作

    python 二维数组的创建 实际上python中的二维数组,主要指的是二维列表 因为python中并没有数组这种数据结构 创建方法:标准方法 lists =[ [] for i in range(3 ...

  9. 经典错误:二维数组与实际矩阵的差异所构成的易错点

    经典错误:二维数组与实际矩阵的差异所构成的易错点 标签:C语言 二维数组 矩阵 by 小威威 1.矩阵与二维数组的差异 在线性代数的课程中,我们接触到了矩阵这一工具,不难发现它很类似于C语言中的二维数 ...

最新文章

  1. php set medias,laravel5.1 -- Integrate FileManager and CKeditor into laravel
  2. 分析隐藏在比特币区块链中的Pony CC服务器
  3. oracle查看数据库名和实例名
  4. Taro+react开发(88):taro条件渲染
  5. Tensorflow入门--图与会话
  6. about semget
  7. pytorch使用早停策略
  8. 第四届蓝桥杯c/c++B组8
  9. python float 精度_改变Float的精度并在Python中存储
  10. [编程题] 被3整除
  11. asp.net中实现登陆的时候用SSL
  12. 低功耗STM32L151+RTC唤醒应用总结
  13. cron表达式每隔1小时一次_cron 每隔1小时50分钟_cron每小时执行一次
  14. php制作600行表格,表格排版的基本操作
  15. 均方根误差(RMSE),平均绝对误差(MAE),标准差(Standard Deviation)的对比
  16. mac 笔记本命令行使用技巧
  17. hadoop java 文件追加_HDFS追加文件
  18. 金融科技大数据产品推荐:恒丰银行实时智能决策引擎
  19. Windows DFS
  20. Android 10 添加安装白名单和卸载黑名单

热门文章

  1. java 继承 String类
  2. # 20155224 实验四 Android程序设计
  3. VM虚拟机Linux克隆后网卡的相关操作
  4. UID 修改 UID 锁死修复
  5. vue 一个组件内多个弹窗_使用vue实现各类弹出框组件
  6. spring配置线程池
  7. nginx配置二级域名
  8. python学习之面向对象学习进阶
  9. java web学习总结(二十一) -------------------模拟Servlet3.0使用注解的方式配置Servlet...
  10. Bean的自动装配Autowiring