Calling DLL Functions From Keyword Tests

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

When calling a DLL routine from TestComplete scripts, you perform a number of preparation actions by calling methods of the DLL program object. You define a DLL type, a routine type, types of routine parameters, load the DLL into memory, etc. (see Calling DLL Functions From Tests - Tutorial for details on this). In this topic we will consider how you can call DLL functions from keyword tests.

The easiest way to call a DLL routine from a keyword test is to create a helper script function that obtains needed parameters to be passed to the DLL routine, performs all needed preparation actions and calls the DLL routine with the specified parameter values and call this script function from the keyword test. Thus, in order to call a DLL routine from your keyword test, you need to perform the following steps:

  1. Create a helper script function that defines the types of the needed dynamic library and the routine to be called, data types of routine parameters, loads the DLL into memory and calls the routine. In the parameters of this helper function, you should specify the values you need to pass from your keyword test to the DLL routine to be called. The script function should pass these values to the DLL routine and return the results of the routine to the keyword test.

    JavaScript, JScript

    function CallDLLRoutine(X, Y, TextToDraw)
    {
      var Def_DLL1, Def_DLL2, LpStr, Lib1, Lib2, dc;
      
      // Defines the dll types
      Def_DLL1 = DLL.DefineDLL("Gdi32");
      Def_DLL2 = DLL.DefineDLL("USER32");
     
      // Registering the function types in TestComplete
      Def_DLL1.DefineProc("TextOutA",
                            vt_i4,
                            vt_i4,
                            vt_i4,
                            vt_lpstr,
                            vt_i4,
                            vt_i4);
                            
      Def_DLL2.DefineProc("GetDC", vt_i4, vt_i4);
      Def_DLL2.DefineProc("ReleaseDC", vt_i4, vt_i4, vt_i4);
                            
      // Creates an alias for TextOutA
      Def_DLL1.DefineAlias("TextOut", "TextOutA");
      
      // Loads the dlls
      Lib1 = DLL.Load("Gdi32");
      Lib2 = DLL.Load("USER32");
     
      // Creates the string parameter
      LpStr = DLL.New("LPSTR", TextToDraw.length);
      LpStr.Text = TextToDraw;
      
      // Gets the device context for drawing
      dc = Lib2.GetDC(0);

      // Calls the TextOutA function from Gdi32.dll
      // The function takes the values passed via the script routine parameters
      res = Lib1.TextOut(dc, X, Y, LpStr, LpStr.Text.length);

      // Releases the device context
      Lib2.ReleaseDC(0, dc);
      
      // Returns results of the TextOutA function
      return res;
    }

    Python

    def CallDLLRoutine(X, Y, TextToDraw):
    
      # Defines the dll types
      Def_DLL1 = DLL.DefineDLL("Gdi32")
      Def_DLL2 = DLL.DefineDLL("USER32")
     
      # Registering the function types in TestComplete
      Def_DLL1.DefineProc("TextOutA", 
                            VT_I4,
                            VT_I4,
                            VT_I4,
                            VT_LPSTR,
                            VT_I4,
                            VT_I4)
                            
      Def_DLL2.DefineProc("GetDC", VT_I4, VT_I4)
      Def_DLL2.DefineProc("ReleaseDC", VT_I4, VT_I4, VT_I4)
                            
      # Creates an alias for TextOutA
      Def_DLL1.DefineAlias("TextOut", "TextOutA")
      
      # Loads the dlls
      Lib1 = DLL.Load("Gdi32")
      Lib2 = DLL.Load("USER32")
     
      # Creates the string parameter
      LpStr = DLL.New("LPSTR", len(TextToDraw))
      LpStr.Text = TextToDraw
      
      # Gets the device context for drawing
      dc = Lib2.GetDC(0)
    
      # Calls the TextOutA function from Gdi32.dll
      # The function takes the values passed via the script routine parameters
      res = Lib1.TextOut(dc, X, Y, LpStr, len(LpStr.Text))
    
      # Releases the device context
      Lib2.ReleaseDC(0, dc)
      
      # Returns results of the TextOutA function
      return res

    VBScript

    Function CallDLLRoutine(X, Y, TextToDraw)

      ' Defines the dll types
      Set Def_DLL1 = DLL.DefineDLL("Gdi32")
      Set Def_DLL2 = DLL.DefineDLL("USER32")
     
      ' Registering the function types in TestComplete
      Call Def_DLL1.DefineProc("TextOutA", _
                            vt_i4, _
                            vt_i4, _
                            vt_i4, _
                            vt_lpstr, _
                            vt_i4, _
                            vt_i4)
                            
      Call Def_DLL2.DefineProc("GetDC", vt_i4, vt_i4)
      Call Def_DLL2.DefineProc("ReleaseDC", vt_i4, vt_i4, vt_i4)

                            
      ' Creates an alias for TextOutA
      Call Def_DLL1.DefineAlias("TextOut", "TextOutA")
      
      ' Loads the dlls
      Set Lib1 = DLL.Load("Gdi32")
      Set Lib2 = DLL.Load("USER32")
     
      ' Creates a string parameter
      Set LpStr = DLL.New("LPSTR", Len(TextToDraw))
      LpStr.Text = TextToDraw
      
      ' Gets the device context for drawing
      dc = Lib2.GetDC(0)

      ' Calls the TextOutA function from Gdi32.dll
      ' The function takes the values passed via the script routine parameters
      res = Lib1.TextOut(dc, X, Y, LpStr, Len(LpStr.Text))

      ' Releases the device context
      Call Lib2.ReleaseDC(0, dc)
      
      ' Returns results of the TextOutA function
      CallDLLRoutine = res
      
    End Function

    DelphiScript

    function CallDLLRoutine(X, Y, TextToDraw);
    var Def_DLL1, Def_DLL2, LpStr, Lib1, Lib2, dc, res;
    begin 
      // Defines the dll types
      Def_DLL1 := DLL.DefineDLL('Gdi32');
      Def_DLL2 := DLL.DefineDLL('USER32');
     
      // Registering the function types in TestComplete
      Def_DLL1.DefineProc('TextOutA',
                            vt_i4,
                            vt_i4,
                            vt_i4,
                            vt_lpstr,
                            vt_i4,
                            vt_i4);
     
      Def_DLL2.DefineProc('GetDC', vt_i4, vt_i4);
      Def_DLL2.DefineProc('ReleaseDC', vt_i4, vt_i4, vt_i4);

      // Creates an alias for TextOutA
      Def_DLL1.DefineAlias('TextOut', 'TextOutA');
      
      // Loads the dlls
      Lib1 := DLL.Load('Gdi32');
      Lib2 := DLL.Load('USER32');
     
      // Creates a string parameter
      LpStr := DLL.New('LPSTR', Length(TextToDraw));
      LpStr.Text := TextToDraw;
      
      // Gets the device context for drawing
      dc := Lib2.GetDC(0);

      // Calls the TextOutA function from Gdi32.dll
      // The function takes the values passed via the script routine parameters
      res := Lib1.TextOut(dc, X, Y, LpStr, Length(LpStr.Text));

      // Releases the device context
      Lib2.ReleaseDC(0, dc);
      
      // Returns results of the TextOutA function
      result := res;
    end;

    C++Script, C#Script

    function CallDLLRoutine(X, Y, TextToDraw)
    {
      var Def_DLL1, Def_DLL2, LpStr, Lib1, Lib2, dc;

      // Defines the dll types
      Def_DLL1 = DLL["DefineDLL"]("Gdi32");
      Def_DLL2 = DLL["DefineDLL"]("USER32");
     
      // Registering the function types in TestComplete
      Def_DLL1["DefineProc"]("TextOutA",
                            vt_i4,
                            vt_i4,
                            vt_i4,
                            vt_lpstr,
                            vt_i4,
                            vt_i4);
     
      Def_DLL2["DefineProc"]("GetDC", vt_i4, vt_i4);
      Def_DLL2["DefineProc"]("ReleaseDC", vt_i4, vt_i4, vt_i4);

      // Creates an alias for TextOutA
      Def_DLL1["DefineAlias"]("TextOut", "TextOutA");
      
      // Loads the dlls
      Lib1 = DLL["Load"]("Gdi32");
      Lib2 = DLL["Load"]("USER32");
     
      // Creates a string parameter
      LpStr = DLL["New"]("LPSTR", TextToDraw["length"]);
      LpStr["Text"] = TextToDraw;
      
      // Gets the device context for drawing
      dc = Lib2["GetDC"](0);

      // Calls the TextOutA function from Gdi32.dll
      // The function takes the values passed via the script routine parameters
      res = Lib1["TextOut"](dc, X, Y, LpStr, LpStr["Text"]["length"]);

      // Releases the device context
      Lib2["ReleaseDC"](0, dc);
      
      // Returns results of the TextOutA function
      return res;
    }

    Note: If the DLL routine you are going to call gets some complex parameters like structures, you need to create appropriate variables in the helper script routine and initialize their members by the values passed via the script routine parameters. For more information, see Using Custom Data Structures in DLL Function Calls.

    For more instructions on calling DLL routines from scripts, see Calling DLL Functions From Tests - Tutorial.

  2. Add the Run Script Routine operation to your keyword test and specify the created helper script routine in its parameters to call the routine from the test.

  3. In the Run Script Routine operation’s parameters, specify values you need to pass via the helper script routine’s parameters:

    Run Script Routine Operation Parameters

    The helper script function gets these parameters and then passes them to the called DLL routine.

  4. The result of the DLL function call is returned by the helper script function. To obtain the result in your keyword test, you can insert the Set Variable Value keyword test operation after the Run Script Routine operation and assign the result of the Run Script Routine operation (that is, the last operation result) to some variable. This can be a keyword test variable, a project or project suite variable. Then you can use the value of this variable in your test. For instance, you can post it to the test log:

    Calling DLL Routines From Keyword Tests

Although the approach described above requires scripting, it allows calling DLL routines from keyword tests and using the returned values in tests.

See Also

Calling DLL Functions From Tests
Calling DLL Functions From Tests - Overview
Calling DLL Functions From Tests - Tutorial

Highlight search results