Functions declared in dynamic link libraries may use parameters of different data types, including parameters of string types like char*
, LPSTR
, LPWSTR
, AnsiString
, PChar
, etc. Passing string values through a DLL function’s parameters from TestComplete tests has some specifics. This topic explains how you can properly create string variables and use them in parameters of a DLL function to be called from your test.
The main specifics of using string parameters when calling DLL functions from TestComplete tests is that you must create helper objects representing string values and pass them to DLL functions instead of using native string variables declared somewhere in script code. To create such a helper object, you should call the DLL.New
method in your test. The method allows creating a new variable of a certain data type (mainly, a custom structure) defined by the DLL.DefineType
method or an array of such variables (see Using Custom Data Structures in DLL Function Calls and Using Arrays in DLL Function Calls). However, TestComplete provides two special data types, LPSTR
and LPWSTR
, that are used to create helper objects for string values to be passed through parameters of DLL functions. These data types are predefined in TestComplete, thus, there is no need to define them with the DLL.DefineType
method. You just need to call the DLL.New
method and specify the predefined LPSTR
constant (or LPWSTR
for Unicode strings) as the data type of the variable to be created.
In case of creating a string variable with DLL.New
, the second parameter of the method (the Count parameter) is used to specify the maximum number of characters that can be contained in the string to be created.
To initialize the created string variable, you can set the needed string value to the Text
property of a helper object returned by DLL.New
.
The following example demonstrates how you can create a string variable that can contain up to 128 characters and initialize it with the needed string value:
JavaScript, JScript
var MyStr = DLL.New("LPSTR", 128);
MyStr.Text = "The quick brown fox jumps over the lazy dog.";
Python
MyStr = DLL.New("LPSTR", 128)
MyStr.Text = "The quick brown fox jumps over the lazy dog."
VBScript
Set MyStr = DLL.New("LPSTR", 128)
MyStr.Text = "The quick brown fox jumps over the lazy dog."
DelphiScript
MyStr := DLL.New('LPSTR', 128);
MyStr.Text := 'The quick brown fox jumps over the lazy dog.';
C++Script, C#Script
var MyStr = DLL["New"]("LPSTR", 128);
MyStr.Text = "The quick brown fox jumps over the lazy dog.";
Note: | The DLL.New method is used if you are going to work with 32-bit DLLs or with 64-bit DLLs only and do not create an environment for loading DLLs of certain “bitness” and calling routines from them (see Specifics of Using 32- and 64-bit DLLs). However, if you explicitly create and use such an environment for DLLs, you need to call the IDLLAccessProcess.New method of an IDLLAccessProcess object that represents an environment for DLLs.
For instance, if you create a 32-bit environment for 32-bit DLLs, you should create string variables in the following way: JavaScript, JScript var MyEnvironment = DLL.DefineEnvironment(true); Python
VBScript Set MyEnvironment = DLL.DefineEnvironment(True) DelphiScript MyEnvironment := DLL.DefineEnvironment(True); C++Script, C#Script var MyEnvironment = DLL.DefineEnvironment(true);
var MyStr = MyEnvironment["New"]("LPSTR", 128); |
After you created and initialized an LPSTR
or LPWSTR
variable, you can pass it like a variable of any other type to the needed function declared in an external DLL. Note that you must first define the needed function in your test by calling the IDefineDLL.DefineProc
method if your DLL was compiled without debug information (see the description of the method for more information about this).
Do not pass native strings through a DLL function’s parameters. You should always create an appropriate variable of the LPSTR or LPWSTR type. The following example demonstrates correct and wrong usage of strings when calling a DLL function:
JavaScript, JScript // A native string variable Python
VBScript ' A native string variable DelphiScript var C++Script, C#Script // A native string variable |
Like variables of any other data types, string variables can be passed through in
, out
or in-out
parameters of a DLL function. In case of out
(in-out
) string parameters, the caller of the function determines the end of the returned string by itself (for instance, it waits for the termination null symbol that indicates the end of the string). Since the called DLL function may return a corrupted string with the incorrectly specified length or end through an out
parameter, TestComplete may receive a huge memory block until it finds the end of such a corrupted string. For such cases, TestComplete uses a special property, IDLLAccessProcessOptions.StringParameterMaxLength
, that specifies the maximum length of a string that can be received by TestComplete from a DLL function via an out
parameter (the default value of the property is 1024). If the length of the returned string exceeds the StringParameterMaxLength
value, TestComplete considers only the first StringParameterMaxLength
characters as the returned string and does not receive the rest of the characters. This allows TestComplete to avoid receiving huge memory blocks with useless data in case of corrupted out
strings.
Variables of the LPSTR type can only be passed from TestComplete tests through parameters of DLL functions. They cannot be used for function results. So, if a function returns a string value (for instance, a char* value in Visual C++ or an AnsiString value in Delphi), you will not be able to obtain the function’s result in your test.
Note for Delphi users: the |
See Also
Calling DLL Functions From Tests - Tutorial
Calling DLL Functions From Tests
Using Custom Data Structures in DLL Function Calls