VARIANT variable is one of the important parameter variables for COM components to communicate with each other. It can contain a variety of different types, such as short, long, double, etc., including various Pointers and arrays. Component calls to each other can be time-consuming, especially when components are in different processes, so reducing the number of passes is an effective way to improve efficiency. Among them, the operation of Excel may involve a large amount of data, so transferring a two-dimensional array at a time improves the operation efficiency of Excel. The operations for the VARIANT two-dimensional array are implemented in two different ways.

1, use SAFEARRAY to achieve two-dimensional array

SAFEARRAY security array can realize multi-dimensional array, SAFEARRAY implementation steps can be roughly divided into three steps.

(1) create SAFEARRAY SAFEARRAY, including setting the type of array elements, dimension of data, size, etc.

(2) Assigning SAFEARRAY array, not only through SafeArrayPutElement function is responsible for each element, but also through the pointer to get SAFEARRAY data address, and then to the pointer to the value of the assignment operation. Among them, if the array in SAFEARRAY is a multidimensional array, that is, the multidimensional array can be converted into a one-dimensional array, and the elements in the array can be manipulated by obtaining a pointer to the array.

(3) Use VARIANT variables to package SAFEARRAY.

Use SAFEARRAR to achieve two-dimensional array source code as follows:


VARTYPE vt = VT_I4; /* Array element type, long*/ SAFEARRAYBOUND sab[2]; / / sab[0]. CElements = 2; sab[0].lLbound = 0; sab[1].cElements = 2; sab[1].lLbound = 0; SAFEARRAY* psa = SafeArrayCreate(vt, sizeof(sab)/sizeof(SAFEARRAYBOUND), sab); if (NULL == psa) { throw; }Copy the code

*/ long (*pArray)[2] = NULL; HRESULT hRet = SafeArrayAccessData(psa, (void **)&pArray); if (FAILED(hRet)) { throw; } memset(pArray, 0, 2*2*sizeof(long)); /* Release pointer to array */ SafeArrayUnaccessData(psa); pArray = NULL; Long index[2] = {0, 0}; 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; }}}

 

/* Convert SAFEARRAY to VARIANT*/ VARIANT var; var.vt = VT_ARRAY | vt; /*vt must be the same data type as psa */ var. Parray = psa; SafeArrayDestroy(psa); psa = NULL;


 

2. Use COleSafeArray to achieve two-dimensional array

COleSafeArray, from VARIANT, is an MFC automation class, so it can only be used when using the MFC class library. COleSafeArray encapsulates operation-related functions. You can query the member functions of this class by MSDN to learn about the functions related to secure arrays. COleSafeArray can also be directly converted to VARIANT. Therefore, COleSafeArray is more convenient to use than SAFEARRAY. The relationship between COleSafeArray and SAFEARRAY is the relationship between the MFC class library and Win32 SDK. The steps are similar.

Use COleSafeArray to implement a two-dimensional array source code as follows:


VARTYPE vt = VT_I4; /* Array element type, 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);Copy the code

*/ long (*pArray)[2] = NULL; olesa.AccessData((void **)&pArray); memset(pArray, 0, 2*2*sizeof(long)); /* Free pointer to array */ olesa.unaccessData (); pArray = NULL;

Long index[2] = {0, 0}; 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); }}

/* Convert the COleSafeArray variable to VARIANT*/ VARIANT var = (VARIANT)olesa;Copy the code


 

The resources

Blog.sina.com.cn/s/blog_74f5… Hfp0601.blog.163.com/blog/static…