Try OpenEdge Now
skip to main content
Programming Interfaces
External Program Interfaces : Shared Library and DLL Support : Using shared libraries
 

Using shared libraries

ABL allows you to access shared libraries either statically or dynamically. Static syntax defines the name, signature (parameters), and location of a shared library during development. Dynamic syntax allows for these definitions to be determined at run time.
Consider the following to determine whether static or dynamic access to a shared library is appropriate for your application:
*Static access is appropriate when the number of parameters and their data type is known at compile time
*Dynamic access is appropriate when:
*The number of parameters and their data type is only known at run time
*You need to invoke a routine that exists in both a Windows DLL and a UNIX shared library
*You need to invoke a routine with a variable number of parameters
To access a shared library routine in ABL do the following:
*Declare each shared library routine
*For static access declare the shared library routine in a manner similar to an ABL internal procedure, using the PROCEDURE statement.
*For dynamic access use the methods and attributes of the call object handle. Create a call object with the CREATE CALL statement, then declare each routine using the call object's CALL-NAME attribute.
*For each shared library input and output parameter definition, specify the parameter data type that matches the C data type of the corresponding routine parameter
*For static access, parameters are defined with the DEFINE PARAMETER statement
*For dynamic access, parameters are defined with the call object's SET-PARAMETER( ) method
*For each ABL variable passed as a routine parameter, ensure that the data type of the variable is compatible with the parameter data type
*Execute the shared library routine
*For static access, use the RUN statement, passing the specified fields, variables, and any required Windows widget handles
*For dynamic access, use the call object's INVOKE( ) method
*Build and manage any structures used by the routine
The following table compares the ABL elements for declaring, accessing, and executing a shared library routine, both statically and dynamically. Options are shown in brackets.
Table 51. Comparison of static and dynamic shared library access
Task
Static
Dynamic (Call object handle)
Name the access point or shared library routine
PROCEDURE proc-name:
CALL-NAME = "proc-name"
Specify the library name
EXTERNAL "dllname"
LIBRARY = "dllname"
Specify the calling convention
[ CDECL | PASCAL | STDCALL ]
LIBRARY-CALLING-CONVENTION = {"CDECL" | "STDCALL"}
Specify the number of the entry point for the routine
[ ORDINAL n]
[ ORDINAL = n ]
Indicate if the shared library remains in memory
[ PERSISTENT ]
[ PERSISTENT = {TRUE | FALSE }]
Define the parameters
[ DEFINE iomode PARAMETER parameterparam-type .]
[ SET-PARAMETER ( parameter-number, data-type, iomode, parameter-value) ]
Parameter iomode options
[ INPUT | OUTPUT | INPUT-OUTPUT | RETURN ]
[ INPUT | OUTPUT | INPUT-OUTPUT ]
Parameter param-type options
[ { LIKE field } | { AS [ HANDLE TO ] data-type } ]
[ [ HANDLE TO ] data-type ]
Expected return data-type by shared library routine
[ DEFINE RETURN PARAMETER parameter AS data-type ]
[ RETURN-VALUE-DLL-TYPE = "data-type" ]
Execute the library routine
RUN proc-name [ ( parameter-list) ].
INVOKE( )
Unload the shared library
RELEASE EXTERNAL [ PROCEDURE ] "dllname".
RELEASE EXTERNAL "dllname".
You can use the call object:
*To invoke an internal or external procedure whose calling sequence (number of parameters and the data type of each) is unknown at compile time
Note: If the name of the procedure is unknown at compile time, use the RUN statement with the VALUE option, and avoid using the call object.
*To invoke a function whose calling sequence is unknown at compile time
Note: If the name of the function is unknown at compile time, use the DYNAMIC-FUNCTION( ) function, and avoid using the call object.
*To reference a widget attribute or a method whose name is unknown at compile time.
If you already know the name of the attribute or procedure, then you also know its syntax, since the name implies certain syntax. If you know the syntax, then you know the calling sequence, since the syntax defines the calling sequence. If you know the calling sequence, you can use widget:attribute or widget:method syntax, and avoid using the call object.
*To dynamically invoke a shared library routine when:
*The number of parameters and their data type is only known at run time
*You need to invoke a routine that exists in both a Windows DLL and a UNIX shared library
*You need to invoke a routine with a variable number of parameters
Note: The 64-bit Windows GUI and character clients ignore the CDECL, PASCAL, and STDCALL calling conventions if they are specified. The 64-bit Windows GUI and character clients always use the standard 64-bit FASTCALL calling convention.