NAG DLLs and PowerBuilder
The following text has been supplied by Sybase.
Description
External functions are functions that are written in languages other than PowerScript and stored in DLLs, known as shared libraries on Macintosh and UNIX. You can use external functions that are written in any language that supports dynamic libraries. Before you can use an external function in a script, you must declare it. You can declare two types of external functions:
- Global external functions: These are available anywhere in the application.
- Local external functions: These are defined for a particular type of window, menu, user object, or user-defined function. These functions are part of the object's definition and can always be used in scripts for the object itself. You can also choose to make these functions accessible to other scripts.
PowerBuilder for Unicode
If you call external functions in an application in PowerBuilder for Unicode, the functions must be defined and compiled with Unicode support. All strings must be passed as Unicode strings. If you call Windows API functions, use the Unicode version of the function name. For example, use FindWindowW (W for wide) instead of FindWindowA (A for ANSI).
Syntax
External function syntax
Use the following syntax to declare an external function:
{ access } FUNCTION returndatatype name ( { { REF }
datatype1 arg1, ..., { REF }
datatypen argn } )
LIBRARY "libname" ALIAS FOR "extname"
External subroutine syntax
You can also declare external subroutines (which are the same as external functions except that they don't return a value) using this syntax:
{ access } SUBROUTINE name ( { { REF }
datatype1 arg1, ..., { REF } datatypen argn } )
LIBRARY "libname" ALIAS FOR "extname"
Parameter Description
Access (optional) (Local external functions only) You can specify Public, Protected, or Private to specify the access level of a local external function (the default is Public).
FUNCTION or SUBROUTINE A keyword specifying the type of call, which determines the way return values are handled. If there is a return value, declare it as a FUNCTION; if it returns nothing or returns VOID, specify SUBROUTINE
| returndatatype: | The data type of the value returned by the function | |
| name: | The name of a function or subroutine that resides in a DLL | |
| REF: | Specifies that you are passing by reference the argument that follows REF. The function can store a value in arg that will be accessible to the rest of the PowerBuilder script | |
| datatype arg: | The data type and name of the arguments for the function or subroutine. The list must match the definition of the function in the DLL. Each datatype arg pair can be preceded by REF LIBRARY "libname" The LIBRARY keyword is followed by a string containing the name of the DLL in which the function or subroutine is stored. Microsoft Windows DLLs usually have the extension DLL or EXE On Windows libname is a dynamic link library, which is a file that usually has an extension DLL or EXEOn Macintosh libname is the name of a fragment defined when you built the shared library, not the name of the file. On UNIX libname is a shared library, which is a file that usually has the extension. So. |
|
| Naming: | Instead of following different naming conventions on each platform, you could use the same library name on all platforms so that function declarations are the same. Enclose the library name in quotation marks and do not include the path. The library must be available to the application at execution time |
ALIAS FOR "extname" (optional)
Keywords followed by a string giving the name of the function as defined in the DLL. If the name in the DLL is not the name you want to use in your script or if the name in the database is not a legal PowerScript name, you must specify ALIAS FOR "extname" to establish the association between the PowerScript name and the external name.
Usage
Specifying access of local functions when declaring a local external function, you can specify its access level—which scripts have access to the function:
Access level
Where you can use the local external function
PublicAny script in the application
Private Scripts
For events in the object for which the function is declared. You cannot use the function in descendants of the object
Protected Scripts
For the object for which the function is declared and its descendants
Use of the access keyword with local external functions works the same as the access-right keywords for instance variables.
Availability of the DLL during execution
To be available to the PowerBuilder application running on any Windows platform, the DLL must be in one of the following directories:
- The current directory
- The Windows directory
- The Windows System subdirectory
- Directories on the DOS path
On Macintosh the shared library is usually stored in the Extensions folder. For more information, see the section on other processing extensions in Application Techniques.
On UNIX update the user's LD_LIBRARY_PATH environment variable to list the directory where the shared library is stored.
Examples
In the Examples60 application that comes with PowerBuilder, these external functions are declared as local external functions in a user object called u_external_function_win32. The scripts that call the functions are user object functions, but since they are part of the same user object, you don't need to use object notation to call them.
Example 1
These declarations allow PowerBuilder to call the functions required for playing a sound in the WIN32 DLL WINMM. DLL:
//playsound FUNCTION boolean sndPlaySoundA (string SoundName, uint Flags) LIBRARY "WINMM.DLL" FUNCTION uint waveOutGetNumDevs ( ) LIBRARY "WINMM.DLL" Unicode versions of Windows API calls Use the Unicode version of the function name in PowerBuilder for Unicode. For example, use sndPlaySoundW instead of sndPlaySoundA. The declarations for WIN16 versions of the functions are similar: //playsound FUNCTION boolean sndPlaySound (string SoundName, uint Flags) LIBRARY "mmsystem.dll" FUNCTION uint waveOutGetNumDevs ( ) LIBRARY "mmsystem.dll"
A function called uf_playsound in the examples50 application provided with PowerBuilder calls the external functions. Uf_playsound is called with two arguments (as_filename and ai_option) that are passed through to sndPlaySoundA. Values for ai_option are as defined in the Win32 documentation, as commented here:
//Options as defined in mmystem.h.
//These may be or'd together.
//#define SND_SYNC 0x0000
//play synchronously (default)
//#define SND_ASYNC 0x0001
//play asynchronously
//#define SND_NODEFAULT 0x0002
//don't use default sound
//#define SND_MEMORY 0x0004
//lpszSoundName points to a memory file
//#define SND_LOOP 0x0008
//loop the sound until next sndPlaySound
//#define SND_NOSTOP 0x0010
//don't stop any currently playing sound
uint lui_numdevs
lui_numdevs = WaveOutGetNumDevs( )
IF lui_numdevs > 0 THEN
sndPlaySoundA(as_filename,ai_option)
RETURN 1
ELSE
RETURN -1
END IF
Example 2
This is the declaration for the Win32 GetSysColor function:
FUNCTION ulong GetSysColor (int index) LIBRARY "USER32.DLL"
This statement calls the external function. The meanings of the index argument and the return value are specified in the Win32 documentation:
RETURN GetSysColor (ai_index)
Example 3
This is the declaration for the Win32 GetSysColor function:
FUNCTION int GetSystemMetrics (int index) LIBRARY "USER32.DLL"
This statement calls the external function to get the screen height:
RETURN GetSystemMetrics(1)
This statement calls the external function to get the screen width:
RETURN GetSystemMetrics(0)