惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Help Net Security
Help Net Security
G
Google Developers Blog
雷峰网
雷峰网
WordPress大学
WordPress大学
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Engineering at Meta
Engineering at Meta
Security Latest
Security Latest
T
Threat Research - Cisco Blogs
AWS News Blog
AWS News Blog
F
Full Disclosure
C
Cybersecurity and Infrastructure Security Agency CISA
T
The Exploit Database - CXSecurity.com
J
Java Code Geeks
U
Unit 42
C
Cyber Attacks, Cyber Crime and Cyber Security
V
V2EX
C
Cisco Blogs
博客园 - 司徒正美
Project Zero
Project Zero
L
LINUX DO - 热门话题
阮一峰的网络日志
阮一峰的网络日志
Blog — PlanetScale
Blog — PlanetScale
Scott Helme
Scott Helme
A
About on SuperTechFans
Hugging Face - Blog
Hugging Face - Blog
S
Securelist
小众软件
小众软件
aimingoo的专栏
aimingoo的专栏
S
Schneier on Security
G
GRAHAM CLULEY
酷 壳 – CoolShell
酷 壳 – CoolShell
Cyberwarzone
Cyberwarzone
MongoDB | Blog
MongoDB | Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 叶小钗
T
Threatpost
Recorded Future
Recorded Future
C
CXSECURITY Database RSS Feed - CXSecurity.com
宝玉的分享
宝玉的分享
N
News and Events Feed by Topic
人人都是产品经理
人人都是产品经理
The Register - Security
The Register - Security
S
Security Archives - TechRepublic
博客园 - Franky
N
News | PayPal Newsroom
Simon Willison's Weblog
Simon Willison's Weblog
S
SegmentFault 最新的问题
W
WeLiveSecurity
A
Arctic Wolf
B
Blog

博客园 - 夜来风雨香

【整理】C#文件操作大全(SamWang)<转> c# 文件及目录操作类 BIOS设置之UEFI/Legacy BIOS切换图文详解 UEFI+GPT引导实践篇(一):切换到UEFI启动,准备安装介质 UEFI+GPT引导实践篇(二):UEFI引导安装64位Win7/Win8 UEFI+GPT引导基础篇(一):什么是GPT,什么是UEFI? 预装WIN8系统的电脑安装WIN7的方法 串口 COM口 TTL RS-232 RS-485 区别 释疑 DataGridView导出到Excel的三个方法 WinForm DataGridView分页功能 C#GridViewExport帮助类,美化导出 C#EXCEL 操作类--C#DataToExcel帮助类 C#EXCEL 操作类--C#ExcelHelper操作类 VS2010 项目引用了DLL文件,也写了Using,但是编译时提示:未能找到类型或命名空间名称 <转> FPGA Verilog HDL 系列实例--------步进电机驱动控制 VS2010+VMWare8+VisualDDK1.5.6 创建并调试你的第一个驱动程序 - 完全教程 USB编程研究之二(常见设备类型的GUID) C++——CString用法大全 C++ 如何有效地使用对话框
C++使用VARIANT实现二维数组的操作
夜来风雨香 · 2014-04-18 · via 博客园 - 夜来风雨香

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/