DefineTypeWithAlignment Method

Applies to TestComplete 14.50, last modified on April 22, 2021

Description

When calling routines from a dynamic link library, you may need to use data types incompatible with OLE. For instance, you may need to call a function that takes a pointer to a structure as a parameter. The IDLLAccessProcess.DefineTypeWithAlignment method "registers" a new data type (normally, a structure) in TestComplete and returns the ID of the new data type. Later, you can use this ID to specify the type of function parameters or structure members.

This method is similar to the IDLLAccessProcess.DefineType method, but it allows you to set alignment for the defined data type.

Declaration

IDLLAccessProcessObj.DefineTypeWithAlignment(TypeNameAlignmentMemberType1MemberName1MemberType2MemberName2, ..., MemberTypeNMemberNameN)

IDLLAccessProcessObj An expression, variable or parameter that specifies a reference to an IDLLAccessProcess object
TypeName [in]    Required    String    
Alignment [in]    Required    Integer    
MemberType1 [in]    Required    Integer    
MemberName1 [in]    Required    String    
MemberType2 [in]    Optional    Integer    
MemberName2 [in]    Optional    String    
...
MemberTypeN [in]    Optional    Integer    
MemberNameN [in]    Optional    String    
Result Integer

Applies To

The method is applied to the following object:

Parameters

The method uses a variable number of parameters.

All parameters of the DefineTypeWithAlignment method, except for the TypeName and Alignment parameters, specify the types and names of structure members. These parameters can be divided into pairs: MemberType-MemberName. Only the first pair is required, other pairs are optional.

TypeName

A required parameter that designates the name of the data type to be defined. TypeName can include any characters. For instance, if you define a structure, this parameter holds the structure name. Later, this name is used to create the structure and fill it with data.

Alignment

Specifies data type alignment.

Alignment must be a power of 2, otherwise, the methods that use this structure will work incorrectly and may cause an access violation error.
MemberType

An integer that specifies the member’s data type. It can be one of predefined constants or an ID created by the previous call to DefineType. For the list of predefined constants, see IDefineDLL.DefineProc.

If a member is passed by a reference, you must use the vt_byref constant when you declare its type (see the example below).

Note that currently it is impossible to call DLL routines that use structures containing array-type members (for instance, string or array fields):

Delphi

// A definition of structure in the DLL source
type
  TMyStruct1 = record
    FInteger:Integer;
    CharArray: array[0..9] of Char; // The array is used
  end;
...
// This routine will not operate properly when it is called from TestComplete
procedure AcceptStructure(const AValue: TMyStruct1); stdcall;

When you try to do this, you will not get an error, but the array-type field will be undefined even if you assign a value to it.

You can workaround this limitation by using pointer-type members:

Delphi

// A definition of structure in the DLL source
type
  TMyStruct2 = record
    FInteger:Integer;
    CharArrPtr: PChar; // The pointer is used
  end;
...
// This routine will function correctly in TestComplete
procedure AcceptStructure(const AValue: TMyStruct2); stdcall;

Make sure that you correctly specified the member types. Incorrect definition of data types may cause TestComplete to shut down when passing such structures to DLL functions from tests (this happens because erroneous definitions may cause incorrect stack processing).
MemberName

The name of the structure member. This name is used to access the structure member from scripts. That is why it must comply with the naming rules of the used scripting language. Besides that, members must have unique names in the structure.

Result Value

The integer value that denotes the identifier of the created data type.

Remarks

DefineTypeWithAlignment registers a new data type, but it does not create variables of this type. To create variables, call IDLLAccessProcess.New.

If the method registers a data type that was registered earlier in the current test or in a previous test (if the ClearSettingsBeforeEach run option is enabled), it posts a warning message to the test log.

The ability to control alignment can be useful when structures with the default alignment work incorrectly (for example, when you use an array of int8 or uint8 values).

Example

The example below demonstrates how to define structures with alignment in TestComplete:

JavaScript, JScript

DefEnv = DLL.DefineEnvironment();
...
int8_type = DefEnv.DefineTypeWithAlignment("INT8", 1, // The name of the new structure and alignment
vt_i1, "Value")// 8-bit integer

Python

DefEnv = DLL.DefineEnvironment()
...
# The 1st and 2nd parameters are the structure name and alignment
# The 3rd parameter is an 8-bit integer value
int8_type = DefEnv.DefineTypeWithAlignment("INT8", 1,\
VT_I1, "Value")

VBScript

Set DefEnv = DLL.DefineEnvironment()
...
' The 1st and 2nd parameters are the structure name and alignment
' The 3rd parameter is an 8-bit integer value
int8_type = DefEnv.DefineTypeWithAlignment("INT8", 1,_
vt_i1, "Value")

DelphiScript

DefEnv := DLL.DefineEnvironment();
...
int8_type := DefEnv.DefineTypeWithAlignment('INT8', 1, // The name of the new structure and alignment
vt_i1, 'Value')// 8-bit integer

C++Script, C#Script

DefEnv = DLL["DefineEnvironment"]();
...
int8_type = DefEnv["DefineTypeWithAlignment"]("INT8", // The name of the new structure and alignment
vt_i1, "Value")// 8-bit integer

See Also

Specifics of Using 32- and 64-bit DLLs
Calling DLL Functions From Tests - Tutorial
IDefineDLL Object
DefineType Method

Highlight search results