1 use safearray
Safearray is an Array Storage Method in VB. Through safearray, you can call each other between VC ++ and VB. Safearray is also a standard Array Storage Method in automation.
1.1 safearray processing functions
Com provides an API for processing safearray. To ensure that the program is unrelated to the safearray Structure[1]In the program, safearray creation, read, change, and release should all be performed through these APIs, instead of directly reading and writing the safearray structure.
The following describes common safearray processing functions.
Create safearray
Safearray * safearraycreate (
Vartype VT,
Unsigned int cdims,
Safearrraybound * rgsabound
);
Safearray safearraycreateex (
Vartype VT,
Unsigned int cdims,
Safearrraybound * rgsabound
Pvoid pvextra
);
Safearray * safearraycreatevector (
Vartype VT,
Long llbound,
Unsigned int celements
);
Safearray * safearraycreatevectorex (
Vartype VT,
Long llbound,
Unsigned int celements,
Lpvoid pvextra
);
Safearraycreate is used to create a common multi-dimensional array. Safearraycreateex is used to create an array of multidimensional custom types or interface pointers. Safearraycreatevector is used to create a one-dimensional Normal Array. Safearraycreatevectorex is used to create a one-dimensional custom type or interface pointer array.
VT Value
Type
Vt_ui1
Unsigned 1-byte INTEGER (byte) array
Vt_ui2
Unsigned 2-byte INTEGER (Word) array
Vt_ui4
Unsigned 4-byte INTEGER (DWORD) array
Vt_uint
Unsigned integer (uint) array
Vt_int
Signed INTEGER (INT) array
Vt_i1
An array of signed 1-byte Integers
Vt_i2
Signed 2-byte integer Array
Vt_i4
Signed 4-byte integer Array
Vt_r4
IEEE 4-byte floating point number (float) array
Vt_r8
IEEE 8-byte floating point number (double) array
Vt_cy
8-byte fixed point currency value Array
Vt_bstr
VB String Array
Vt_decimal
12-byte fixed point (large number) array
Vt_error
Array of standard error numbers
Vt_bool
Boolean Array
Vt_date
Date Array
Vt_variant
VB variant array
Llbound is the minimum subscript of the array and can be a negative number. Celements is the length of the array. The maximum subscript value of the array is the minimum subscript plus the length of the array minus one.
The safearraycreatevector function returns a pointer to the safearray structure.
2. safearraycreatevectorex
Safearray * safearraycreatevectorex (
Vartype VT,
Long llbound,
Unsigned int celements,
Lpvoid pvextra
);
This function is used to create a safearray array of a custom type or a COM object. Similar to safearraycreatevector, safearraycreatevector also has three parameters: type, lower bound, and length. Safearraycreatevectorex also adds the pvextra parameter.
The meaning of pvextra is related to the value of VT. When the value of VT is in the table above, the value of pvextra does not work. When VT is set to vt_record, safearraycreatevectorex returns an array of the custom type (structure or union. In this case, pvextra must be a pointer to irecordinfo.
When the VT value is vt_unknown or vt_dispatch. Pvextra is a pointer to the IID (interface guid. In the current COM specification, pvextra can only be iid_iunknown and iid_idispatch. The value must be the same as that of VT.
A. Create a custom Array
When VT is vt_record. Pvextra must be an irecordinfo pointer. In most cases, we obtain the irecordinfo pointer of the custom type from TLB. The following code retrieves irecordinfo:
Irecordinfo * precordinfo;
HR = getrecordinfofromguids (
Libid,
Majorver,
Minorver,
Locale_user_default,
Typeguid,
& Precordinfo );
In the above Code, Libid is the guid Of The TLB, majorver and minorver are the master and minor version numbers of TLB, and typeguid is the guid of the custom structure.
The function returns a pointer to the irecordinfo interface.
B. Create a COM Object Array
To create a com array, you can use the iunknown pointer or the idispatch pointer. If you want to use other pointer types, you should use the QueryInterface method instead of directly saving them in the array. Because the serialization program of the safearray can only process iunknown and idispatch pointer types, if you place pointers of other Interface Types in the array, problems may occur during cross-Suite use.
Read and Write the safearray.
When reading and writing the safearray array. Use the standard API provided by COM. Com provides a large number of functions for safearray operations. This article uses only two of these functions, safearrayaccessdata and safearrayunaccessdata, and some auxiliary functions. These two functions can be used to perform all Array Operations. Other functions are used to operate a single element. They are not described in this article because they are not used much and are inefficient.
1. safearrayaccessdata
This function is used to obtain the data pointer of the safearray and lock the data of the safearray. After obtaining the Data Pointer, you can directly access the data in the safearray array.
If the array type is type, the obtained data pointer is actually the address of the type array. In the case of multi-dimensional arrays, the subscript of multiple dimensions must be converted into one-dimensional subscript for access.
2. safearrayunaccessdata
This function is used to unlock the safearray data. After unlocking, the Data Pointer should not be read or written. If you want to access the service, you must obtain and lock the data again.
3. Determine the Array Structure
Before accessing an array, you must know the data type, dimension, and lower bound and length of each dimension in the array. Com provides functions to obtain these array parameters.
Obtain the type and return the enumerated values of the type starting with "VT:
Hresult safearraygetvartype (
Safearray * PSA,
Vartype * pvartype );
Returns the dimension of the array:
Uint safearraygetdim (
Safearray * PSA );
Obtain the attributes of each dimension and return the upper and lower bounds of the specified dimension (Ndim starts from 1 ):
Hresult safearraygetlbound (
Safearray * PSA,
Uint Ndim,
Long * plbound );
Hresult safearraygetubound (
Safearray * PSA,
Uint Ndim,
Long * pubound );
Get the custom type interface. For the custom structure array, return the pointer of the custom structure type data:
Hresult safearraygetrecordinfo (
Safearray * PSA,
Irecordinfo ** pprecordinfo );
4. access a common one-dimensional array
The pointer returned from safearrayaccessdata is actually a one-dimensional array address in C language. In VC ++, you can read and write this array just like accessing a normal array.
Note that in C, all array subscript starts from 0. In safearray, the array subscript can start with any number. Therefore, conversion is required before access. The conversion method is to subtract the lower bound of the array from the subscript of safearray to obtain the subscript of the array in C language.
As follows:
Type * pdata;
Long lbound;
Safearrayaccessdata (PSA, (void hugep **) & pdata );
Safearraygetlbound (PSA, 1, & lbound );
Type item = pdata [n-lbound];
5. Access multi-dimensional arrays
Accessing a multi-dimensional array is similar to accessing a one-dimensional array. You only need to convert a multi-dimensional subscript to a one-dimensional subscript. The method for converting multi-dimensional subscripts into one-dimensional subscripts is similar to that described in array pointers.
Set: There are n dimensions. The length of each dimension (the upper bound minus the lower bound plus one) is L1, L2 ,... And ln. The subscript to be converted is x1, x2 ,... , Xn. You can convert it to the subscript of a one-dimensional array according to the following formula.
X1 + x2 * l1 + X3 * (L1 * l2) + X4 * (L1 * L2 * l3) +... + Xn * (L1 * L2 *... * L (n-1 ))
6. Access the custom structure array
When accessing the custom structure array, you can use the Type Definitions automatically generated by # iimport or compiled by IDL. If there is no way to get the declaration of the custom structure, you can use the method in the irecordinfo interface to indirectly access the custom structure.
First, you need to get the length of the custom structure, which can be obtained through the irecordinfo: getsize method.
Access the fields in the Custom structure through the irecordinfo: getfield and irecordinfo: putfield methods.
You can use other methods in irecordinfo to obtain the attribute content of each field. You can refer to the relevant documentation.
Release the safearray Array
The safearray array should be released using the support functions of COM:
Hresult safearraydestroy (safearray * PSA );
1.3 Use The IDL definition of safearray
Each interface generates proxy and placeholder code through IDL. To enable the proxy and placeholder program to serialize parameters correctly, the IDL definition must be correctly written.
The midl tool directly supports the transmission of safearray data. However, the safearray pointer must be used to transmit the safearray data. The difficulty lies in that the addition method of VC ++ 6.0 and the tool for adding attributes cannot correctly process the safearray array.
In IDL, the array type must be specified as follows:
[ID (10)] hresult Foo ([in] safearray (long) pparam );
In the implemented function declaration, the corresponding pointer type should be used:
Hresult Foo (safearray * pparam );
For array parameters of the output and input/output types, pointer parameters must be used in IDL, while double pointers are used in function declaration.
[ID (11)] hresult foo2 ([out] safearray (long) * ppparam );
The function declaration is as follows:
Hresult foo2 (safearray ** ppparam );
1.4 variant and safearray
In VB interfaces, array parameters are often transmitted through variant. Here we will briefly describe the notes for passing the Array Using the variant parameter.
Input Array
For input arrays, you can use the variant pointer or the variant type parameter. In both cases, the types in variant are different.
When the variant pointer is used, the type of the input variant parameter (Vt parameter value) is vt_array | vt_byref | vt_xxx. In this case, use the pparray field of the variant parameter to obtain the safearray pointer.
If the parameter is variant, the type of the input variant parameter (Vt parameter value) is vt_array | vt_xxx. Use the parray field of the variant parameter to obtain the safearray pointer.
In both cases, the variant type is different, so the code is also different.
Output Array
The variant pointer must be used for output and input/output arrays. The variant type is vt_arrya | vt_byref | vt_xxx.
1.5 safearray Memory Management
Use com-specific API functions to create and destroy safearray.
For the input safearray, the caller is responsible for creating and destroying the safearray. For the output safearray, the caller creates the safearray and the caller destroys it. For the input and output safearray, the caller creates the safearray, the called party can destroy and recreate the object, and the caller will destroy the object.