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);
/*把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);
olesa.AccessData((void **)&pArray);
olesa.UnaccessData();
olesa.GetLBound(1, &lFirstLBound);
olesa.GetUBound(1, &lFirstUBound);
olesa.GetLBound(2, &lSecondLBound);
olesa.GetUBound(2, &lSecondUBound);
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/