🛠️ P3/COBOL 25.1.0-SNAPSHOT is available for preview.
User Guide
Calling External (non-COBOL) Programs

Calling External (non-COBOL) Programs

When a CALL statement is executed by the COBOL program, the program to be called is determined in the following way:

First, the program name supplied in the CALL (either a literal name, or the value of a data item containing the name) is matched to any name-pattern occurring in program-association option elements configured for the calling program. If a match occurs, the class-name indicated replaces the call-supplied name according the class-name substitutions specified, if any. If no match occurs, the called program name is the call-supplied name. In both cases, this results in the effective name of the called program.

Next, the effective name is assumed to represent a nested program class at the next lower level of the calling program's nesting level. If this matches a nested program, it is called as the target program.

If not, the effective name is assumed to be a COMMON program. If it is the case, the COMMON program is called as the target program.

If the effective name refers neither to a nested nor a COMMON program, it is assumed to refer to a Java class extending the Program object (as are all top-level P3/COBOL generated classes) and it is loaded by the Java class loader and executed.

If the class is not found, the effective name is deemed to be an external program, and the configuration described here controls the determination of the target and the means of calling it.

First, the effective name is checked to see if it refers directly to a shared object file. This is the case if the file name ends with .so, .dll or .dynlib. If so, the list of directories specified by the <external-library-directories> runtime configuration element, if present, is searched and, if found, the file is loaded and the CALL statement returns immediately to the COBOL program. In this case, no function within the called shared program file is actually performed, the file is just loaded into the process memory and made available to the COBOL for subsequent calls.

If the effective name does not refer to a shared object file, it is assumed to be a function name within an external library specified by the <external-call-strategy> configuration element that follows. The libraries are examined in the order specified and, when a function within a library matches the effective name, that function becomes the target program and is called using the calling convention determined by the library's call strategy.

Finally, if the call resulted in the loading of a shared library rather than calling a specific function (i.e., the <external-library-directories> element determined the file), a subsequent CANCEL statement may be used to cause the unloading of the loaded shared file if it is unloadable.

External CALL Strategy Configuration

The <external-call-strategy> element is used to configure the shared object libraries to be used by the program and the order in which they are to be examined for the CALLed entry points.

The format of the external call strategy element is:

runtime.p3c
<external-call-strategy>
    <load-process>true|false</load-process>
    <library>
        <file>*.dll|*.so|*.dylib</file>
        <call-convention>NATIVE|CDECL|STDCALL</call-convention>
    </library>
 
    <library>
        <file>*.dll|*.so|*.dylib</file>
        <call-convention>NATIVE|CDECL|STDCALL</call-convention>
    </library>
</external-call-strategy>
OptionDescription
load-processWhen set to true, this element directs the P3/COBOL external loader to consider all shared objects loaded in the current JVM process to be accessible to the running program.
For example, this option when set means that a dll (or so, dynlib) loaded prior to the start of the JVM would be made available just as if it had been specified explicitly using the library element described below.
libraryThis element encloses the description of a dynamic shared object library file that is to be search during the appropriate phase of the loading process.
fileThis element contains the path (either absolute or relative to the current directory) if a dynamic shared object file.
call-conventionHistorical selector retained for configuration compatibility. Possible values are NATIVE, CDECL, and STDCALL. On supported 64-bit platforms the Java Foreign Function and Memory API uses the platform ABI for all three values (they are equivalent). STDCALL is rejected on 32-bit Windows. NATIVE is the default if this element is not present in a library element.

External Library Directories Configuration

If the calling COBOL program wishes, at runtime, to make available a specific shared object that is not made available by the external-call-strategy element, it may call the shared object file by name, thus loading it and making it available just as if it had been loaded by the configuration option. If this is the case, the external-library-directories configuration element provides the directory paths to be searched to find the called shared object.

runtime.p3c
<external-library-directories>path path ... path</external-library-directories>

The paths to the desired libraries are in the form of an XML list, that is space separated.