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, 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实现二维数组的操作的更多相关文章
- C++程序设计实践指导1.2二维数组的操作运算改写要求实现
改写要求1:改写为以单链表表示二维数组 #include <cstdlib> #include <iostream> using namespace std; struct L ...
- nRF51800 蓝牙学习 进程记录 2:关于二维数组 执念执战
前天在玩OLED时想完成一直想弄得一个东西,就是简单的单片机游戏.因为STM32和nRF51822的内存足够,所以就用缓存数组的方法来显示图像(我也不知道术语是啥,反正就是在内存中建立一个128X64 ...
- 对二维数组使用指针进行操作的探索(C语言)
/* Name: 对二维数组使用指针进行操作的探索 Copyright: Author: lingr7 Date: 01/12/18 11:55 Description: */ #include< ...
- 二维数组是二级指针pointer to pointer!
二维数组居然是个类似于二级指针(pointer to pointer)的东西,十分震惊! #include <stdio.h> int main() { ][]={{,,,},{,,,}, ...
- VueX中直接修改数据报错,修改一维数组,二维数组,报错的原因
直接修改state中的的数据是不被允许的,会报错 这个时候可以使用三种种方式处理 第一种:使用拓展运算符,深拷贝一维数组或对象var arrA = [1,2,3,4]var a = [...arr]| ...
- PHP 二维数组根据某个字段排序
二维数组根据某个字段排序有两种办法,一种是通过sort自己写代码,一种是直接用array_multisort排序函数 一. 手写arraysort PHP的一维数组排序函数: sort 对数组的值按 ...
- 剑指Offer-【面试题03:二维数组中的查找】
package com.cxz.question3; /* * 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序. * 请完成一个函数,输入这样的一个二维数组和 ...
- PHP开发笔记:二维数组根据某一项来进行排序
比如说我们现在有一个二维数组: $arr = array( ‘d' => array(‘id' => 5, ‘name' => 1, ‘age' => 7), ‘b' => ...
- 剑指Offer面试题:2.二维数组中的查找
一.题目:二维数组中的查找 题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. ...
随机推荐
- RichTextBox文字处理控件属性介绍
RichTextBox控件是一种既能够输入文本. 又能够修改文本的文字处理控件, 与TextBox控件比较, RichTextBox控件的文字处理功用更加丰厚, 不只能够设定文字的色彩. 字体, 还具 ...
- innerHTML,innertext ,textcontent,write()
innerhtml属于对象的一个属性,一般用于向已经存在的标签中写入内容,或者读取标签的内容. innertext属于对象的一个属性,一般只能用于写入内容,或者读取内容,不能读取dom 中的标签,且只 ...
- zookeeper安装配置
以3.3.3为例(当然,前提是要安装好jdk,zookeeper的启动时依赖于jdk的) (1) wget http://www.apache.org/dist//zookeeper/zookeepe ...
- 2016 - 1 - 23 json转模型 常用的第三方框架
一: 三个常用的框架 1. Mantle - 所有模型必须继承MTModel 2. JSONModel - 所有模型必须继承JSONModel 3.MJExtension - 不需要继承任何东西. - ...
- IOS 验证码
将十六进制的字符串转化为UIImage 最近写一个项目,有验证码,但是接口返回的并不是验证码图片的URL,而是返回的字节数组16进制字符串.这样就需要把16进制字符串首先字节数组,其次再把字节数组转化 ...
- 期望DP
BZOJ 1415 #include <iostream> #include <cstring> #include <algorithm> #include < ...
- HDU 4768 (二分区间---涨姿势)
题意:告诉n组A,B,C,按照A + k * C生成等差数列,问这n组数列中哪个数字出现了奇数次以及出现了几次,题目保证最多只会出现一个这种数字. 分析:读完题并没有思路,后来知道是二分区间,枚举是哪 ...
- 修改mysql用户名密码 和 PHPmysqlAdmin对应密码修改
本地的mysql运行时,可能会用到修改用户名密码: mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('输入新密码');不存在修改用户啊 ...
- 9.9,新iPhone要来了,是欢呼,还是墙角画圈,一会儿见分晓
- web安全之sql注入联合查询
联合查询的条件: 有显示位.当然要有注入点!! 提前需要了解的函数: union可合并两个或多个select语句的结果集,前提是两个select必有相同列.且各列的数据类型也相同 distinct 去 ...