C++使用VARIANT实现二维数组的操作

简介: VARIANT变量是COM组件之间互相通信的重要的参数变量之一,它可以容纳多种不同的类型,如short、long、double等,包括各类指针和数组。组件之间的互相调用是比较耗时的,尤其带当组件位于不同进程中时,因此,减少传递次数是提高效率的一种有效方法。

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/

 
 
 
相关文章
|
1月前
|
存储 C++ 容器
c++vector容器-赋直操作讲解
c++vector容器-赋直操作讲解
34 0
|
20天前
|
人工智能 机器人 C++
【C++/Python】Windows用Swig实现C++调用Python(史上最简单详细,80岁看了都会操作)
【C++/Python】Windows用Swig实现C++调用Python(史上最简单详细,80岁看了都会操作)
|
1月前
|
存储 JSON 安全
【C++ JSON库 json值的创建手段】深入探究C++中JSON对象定位与操作:从引用到回调函数
【C++ JSON库 json值的创建手段】深入探究C++中JSON对象定位与操作:从引用到回调函数
66 0
|
26天前
|
C语言 C++
C/C++文件读取操作
C/C++文件读取操作
|
1月前
|
存储 算法 数据管理
C++中利用随机策略优化二叉树操作效率的实现方法
C++中利用随机策略优化二叉树操作效率的实现方法
77 1
|
1月前
|
存储 缓存 调度
C++关联容器深度解析:提升数据结构操作的艺术
C++关联容器深度解析:提升数据结构操作的艺术
74 0
|
1月前
|
存储 程序员 C++
在C++语言中顺序容器的操作
在C++语言中顺序容器的操作
12 0
|
1月前
|
存储 C++ 索引
C++中的string容器及字符串拼接操作讲解
C++中的string容器及字符串拼接操作讲解
19 3
|
1月前
|
存储 编译器 C++
c++二维数组定义方程的讲解
c++二维数组定义方程的讲解
9 0
|
2月前
|
算法 测试技术 C++
【数论】【分类讨论】【C++算法】1611使整数变为 0 的最少操作次数
【数论】【分类讨论】【C++算法】1611使整数变为 0 的最少操作次数