Loading DLLs with the CALL Statement

To load the dynamic link library "mylib.dll", you would CALL either "mylib.dll" or simply "mylib". The runtime automatically appends ".dll" when searching for a DLL. The runtime searches for DLLs after it has searched for COBOL programs. It first searches the paths defined in the CODE_PREFIX configuration variable, and then in the System and Windows folders, respectively (actually, folder names vary depending on the specific version of Windows and user customizations). If you do not want the runtime to look in the System or Windows folders, set the DLL_USE_SYSTEM_DIR configuration variable to "0" (off, false, no).

Note: By default, the runtime also recognizes ".drv" and ".ocx" files, which enables you to load these file types just as you would a ".dll". For backwards compatibility, you can turn this feature off by setting the runtime configuration variable "USE_WINSYSFILES" to "0" (off, false, no). Then, only calls to ".dll" files are supported.

You can give the runtime a simpler name for a DLL. The runtime will prepend various append various suffixes to the name given, searching sequentially through the list of names until a name is found that can be loaded.

On Windows, the runtime will first try the name as given and then append in order ".dll" and ".ocx".

The CALL statement that loads a DLL simply makes the routines contained in the DLL available to the COBOL program. The one exception to this is if the DLL contains a routine whose name is the same as the DLL. In this case, the routine is immediately called. For example, if the DLL "mylib.dll" contains a routine called "mylib", then

CALL "mylib"

both loads the DLL and executes the MYLIB routine. To load the library and avoid calling the subroutine of the same name, specify ".dll" explicitly in the CALL statement, as shown below:

CALL "mylib.dll"

Thin client applications may call DLLs on the display host (client) by adding "@[DISPLAY]:" to the beginning of the CALL name. For example, to call a DLL named "mylib" on the client, you would use the following code:

CALL "@[DISPLAY]:mylib.dll" 

For complete information, Calling Dynamic Link Libraries (DLLs), in the AcuConnect User's Guide.

Once the library has been loaded, all of the routines it contains can be called. For example:

CALL "funcA"

Loaded DLLs are searched immediately prior to searching for COBOL programs on disk. Routines contained in a DLL are called using either the direct C interface or the Pascal/WINAPI interface. As a result, you may pass parameters BY VALUE if that is required by the routine.

Routines called by this method are assumed to use either the cdecl (standard C) or stdcall (Pascal/WINAPI) parameter passing conventions. Most of the Windows API library functions are stored in DLLs and must be called using the stdcall (Pascal/WINAPI) calling convention.

By default, the runtime uses the value of the DLL_CONVENTION configuration variable to determine the calling convention. A maximum of 16 parameters can be passed using the stdcall DLL_CONVENTION. A maximum of eight parameters can be passed using the cdecl (standard C) DLL_CONVENTION (the default). See DLL_CONVENTION for more details. If you attempt to call a routine that uses a different calling convention, the results are undefined (and usually fatal).

You can override the calling convention for an individual function by specifying it after the function name in the CALL statement.

To specify the stdcall calling convention, append one of the following strings to the function name: @, @1, @WINAPI, @__stdcall. (The @__stdcall string has two underscores.) For example:

CALL "funcA@"

or

CALL "funcA@1"

or

CALL "funcA@WINAPI"

or

CALL "funcA@__stdcall"

calls funcA using the stdcall calling convention.

To specify the cdecl calling convention, append one of the following strings to the function name: @0, @STDC, @__cdecl. (The @__cdecl string has two underscores.) For example:

CALL "funcB@0"

or

CALL "funcB@STDC"

or

CALL "funcB@__cdecl"

calls funcB using the cdecl calling convention.

The runtime uses the specified calling convention and ignores the value of the DLL_CONVENTION configuration variable. Note that you cannot specify the calling convention for a DLL when specifying a DLL name in a CALL statement. You can, however, specify the calling convention for DLLs using configuration variables. Specifying conventions for individual functions in the CALL statement overrides any other conventions specified for the DLL name.

If desired, you could specify the calling convention for individual functions in the runtime configuration file instead of in the CALL statement. To do this, set the CODE_MAPPING variable to "1". If you use the following configuration entries:

CODE_MAPPING=1
funcA=funcA@__stdcall
funcB=funcB@__cdecl 

then

CALL "funcA"

calls funcA using the stdcall calling convention and

CALL "funcB" 

calls funcB using the cdecl convention.

If you have access to a library (".lib") file for the DLL, you can determine the calling convention for a particular function using the Microsoft COFF Binary File Dumper utility. Run "dumpbin /exports <library name>". If the function name is preceded by an underscore and followed by an "at" sign ("@") and a decimal number, the function expects to be called using the stdcall calling convention. If the name of the function is not followed by an at sign, then the function expects to be called using the cdecl convention.

Like other programs that are loaded with a CALL statement, you can unload a CALLed DLL with a CANCEL statement. When you CANCEL a DLL, you may no longer call its component libraries. Also, unless the logical cancels feature is enabled, all memory used by the program is released. For information about runtime memory management and the logical cancels feature, see Memory Management.

Note: The CANCEL_ALL_DLLS configuration variable can be used to control whether CANCEL ALL frees DLLs. See CANCEL ALL for more details.