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.
| A function must use the standard calling convention and be exported. |
If you would like to view the names of the functions that are exported from a DLL, use the following steps.
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.
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:
| An extension library must always have the exported functions TPExtensionStart and TPExtensionStop. |
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.
| /*----------------------------------------------------------------------------*/ #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 |