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; /*对二维数组的元素进行逐个赋值*/ longindex[2]={0,0}; longlFirstLBound=0; longlFirstUBound=0; longlSecondLBound=0; longlSecondUBound=0; SafeArrayGetLBound(psa,1,&lFirstLBound); SafeArrayGetUBound(psa,1,&lFirstUBound); SafeArrayGetLBound(psa,2,&lSecondLBound); SafeArrayGetUBound(psa,2,&lSecondUBound); for(longi=lFirstLBound; i<=lFirstUBound; i++) { index[0]=i; for(longj=lSecondLBound; j<=lSecondUBound; j++) { index[1]=j; longlElement=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; /*对二维数组的元素进行逐个赋值*/ longindex[2]={0,0}; longlFirstLBound=0; longlFirstUBound=0; longlSecondLBound=0; longlSecondUBound=0; olesa.GetLBound(1,&lFirstLBound); olesa.GetUBound(1,&lFirstUBound); olesa.GetLBound(2,&lSecondLBound); olesa.GetUBound(2,&lSecondUBound); for(longi=lFirstLBound; i<=lFirstUBound; i++) { index[0]=i; for(longj=lSecondLBound; j<=lSecondUBound; j++) { index[1]=j; longlElement=i*sab[1].cElements+j; olesa.PutElement(index,&lElement); } } /*把COleSafeArray变量转换为VARIANT*/ VARIANT var = (VARIANT)olesa; 参考资料 http://blog.sina.com.cn/s/blog_74f586a50100rv6t.htmlhttp://hfp0601.blog.163.com/blog/static/228483522011031104718762/