[top] [up] [next]

An empty extension library


Function requirements

An extension library can be created with any programming tool as long as the functions inside the Windows DLL use the standard calling convention for passing parameters and returning values. Functions that use the standard calling convention must pass the correct number of arguments and the type of each argument.

In a typical C/C++ programming tool the keyword __stdcall can be used for declaring a function to use the standard calling convention. The C/C++ header file defines the macro TP_API to force functions to use the standard calling convention. In Delphi the stdcall directive must be used.

The functions that Trinc-Prolog will call must be exported by the DLL. Trinc-Prolog uses the Windows API function GetProcAddress to dynamically link to functions inside a DLL. Exporting a function can be done by listing the name of the exported function in the exports section of a .DEF file (definition file) or using a keyword in the source like __export. In Borland Delphi it is possible to export functions by listing these functions in the exports clause of a library.

Arrow.gif (1632 bytes) A function must use the standard calling convention and be exported.

 

Viewing exported functions

If you would like to view the names of the functions that are exported from a DLL, use the following steps.

  1. Click the DLL with the right mouse button.
  2. Click Quick View from the popupmenu.
  3. Scroll to the heading, Export Table. The table contains the ordinal, entry point, and name for each export.

Your linker (or a similar tool) may also provide a list of exported functions. For more information, see the documentation included with your development tools.

DLL requirements

A correct Trinc-Prolog extension library must at least have two exported functions, these functions must be called TPExtensionStart and TPExtensionStop.

The function TPExtensionStart is called by Trinc-Prolog after the extension library was successfully loaded into memory and after Trinc-Prolog has checked that the extension contains functions with the name TPExtensionStart and TPExtensionStop.

An extension library is loaded into memory if Trinc-Prolog encounters a predicate or class which was declared as an external predicate or class. An extension library is removed from memory if Trinc-Prolog stops or by the predicate unload_external_library/1.

The steps for loading an extension library are:

  1. An external predicate or class is being used in a Prolog program.
  2. Trinc-Prolog checks if the associated extension library is loaded, if the extension library is not loaded then continue with step 3, else continue with step 6.
  3. The subfolder plugin is searched for the file of the extension library, if the file is not found then the current folder of the Trinc-Prolog executable is also searched. If the file was found then continue with the step 4, else an exception is thrown.
  4. Trinc-Prolog checks if the extension contains the functions TPExtensionStart and TPExtensionStop, if these functions are inside the extension then continue with step 5.
  5. The function TPExtensionStart is executed.
  6. The external predicate or class is called.
Arrow.gif (1632 bytes) An extension library must always have the exported functions TPExtensionStart and TPExtensionStop.

 

 

Source example

Below there is an example of a minimal extension library, it just implements the functions TPExtensionStart and TPExtensionStop. The file "tpexten.h" that is included contains the types and functions that can be used by extension libraries. All the types that begin with the characters TP are defined in this file.

Arrow.gif (1632 bytes) Delphi example

 

/*----------------------------------------------------------------------------*/

#include <windows.h>
#include "tpexten.h" /* Extension types */

/*----------------------------------------------------------------------------*/

/* Global data of the DLL */
HINSTANCE DllInstance; /* Instance handle of the DLL */

/*----------------------------------------------------------------------------*/

#ifdef __cplusplus
extern "C" {
#endif

TPBOOL TP_API TPExtensionStart( TPINT32 Id, TPINIT *Init, TPEXCEPTION *Exc );
TPBOOL TP_API TPExtensionStop( TPINT32 Id );

#ifdef __cplusplus
}
#endif

/*----------------------------------------------------------------------------*/

#pragma argsused
int WINAPI DllEntryPoint( HINSTANCE Instance, DWORD Reason, PVOID Reserved ) {
/* Func - Respond to the attaching | detaching of a process or a thread to the DLL.
* Pre - TRUE.
* Post - TRUE was returned.
*/

    switch( Reason ) {
      case DLL_PROCESS_ATTACH: {
        DllInstance = Instance;
        break;
        }
      case DLL_PROCESS_DETACH: {
        break;
        }
      case DLL_THREAD_ATTACH:
      case DLL_THREAD_DETACH: {
        break;
        }
      default:
        break;
      }/*switch*/
    return TRUE;
}

TPBOOL TP_API TPExtensionStart( TPINT32 Id, TPINIT *Init, TPEXCEPTION *Exc ) {
/* Func - This function is called by Trinc-Prolog when the DLL is loaded for the
* first time. The parameter is the ID number of a Trinc-Prolog engine
* loading the extension.
* Pre - TRUE.
* Post - The DLL was initialised and can be used if TRUE was returned, else was
* FALSE returned. If this function returns FALSE the extension DLL is
* unloaded again.
*/

    return TRUE;
}

TPBOOL TP_API TPExtensionStop( TPINT32 Id ) {
/* Func - This function is called if Trinc-Prolog unloads the DLL from memory.
* The parameter is the ID number of a Trinc-Prolog engine unloading the
* extension.
* Pre - TRUE.
* Post - TRUE.
*/

return TRUE;
}

The definition file for this DLL may look like the example below:

;-------------------------------------------------------------------------------
; FILE: DLLEXT1.DEF
; List of the exported functions of a Trinc Prolog extension DLL.
; TRINC (C) 2000
;-------------------------------------------------------------------------------

EXPORTS
    TPExtensionStart
    TPExtensionStop

[top] [up] [next]

 

info@trinc-prolog.com