Use the array parameter-safearray in COM

Source: Internet
Author: User

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.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.