A simple DLL application contains object modules that are made up of only DLL-code. The application may consist of multiple source modules. Some of the source modules may contain references to imported functions, imported variables, or both.
It is not necessary for DLL applications to be reentrant. However, for some compilers it is necessary to compile code that references DLLs with the RENT option in order to provide support for the DLL call mechanism.
Write your code as you would if the functions were statically bound. Assembler code that will access imported functions and imported variables must use the Language Environment macros.
After final autocall processing of DD SYSLIB is complete, all DLL-type references that are not statically resolved are compared to IMPORT control statements. Symbols on IMPORT control statements are treated as definitions, and cause a matching unresolved symbol to be considered dynamically rather than statically resolved. A dynamically resolved symbol causes an entry in the binder B_IMPEXP to be created. If the symbol is unresolved at the end of DLL processing, it is not accessible at run time.
Addresses of statically bound symbols are known at application load time, but addresses of dynamically bound symbols are not. Instead, the runtime library that loads the DLL that exports those symbols finds their addresses at application run time. The runtime library also fixes up the importer's linkage blocks (descriptors) in C_WSA during program execution.
The following code fragment illustrates how a C++ application can use the TRIANGLE DLL described inWriting your C++ DLL code. Compile normally and bind with the definition side-deck provided with the TRIANGLE DLL.
extern int getarea(); /* function prototype */
main() {
...
getarea(); /* imported function reference */
...
}
The following COBOL code sample illustrates how a simple COBOL-only DLL application (A1C4DL01) calls a COBOL DLL (A1C4DL02):
CBL PGMNAME(LONGMIXED),DLL,RENT
IDENTIFICATION DIVISION.
PROGRAM-ID. 'A1C4DL01'.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
01 TODAYS-DATE-YYYYMMDD PIC 9(8).
PROCEDURE DIVISION.
Display 'A1C4DL01: Entered'
MOVE FUNCTION CURRENT-DATE(1:8) TO TODAYS-DATE-YYYYMMDD
Call 'A1C4DL02' using todays-date-yyyymmdd
Display 'A1C4DL01: All done'
GOBACK
.
CBL PGMNAME(LONGMIXED),DLL,EXPORTALL,RENT
IDENTIFICATION DIVISION.
PROGRAM-ID. 'A1C4DL02'.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
LINKAGE SECTION.
01 TODAYS-DATE-YYYYMMDD PIC 9(8).
PROCEDURE DIVISION using todays-date-yyyymmdd.
Display 'A1C4DL02: Todays date is ' todays-date-yyyymmdd
GOBACK
.
DLLAPPL CEEENTRY MAIN=YES,PPA=DLLPPA
* Symbolic Register Definitions and Usage
R8 EQU 8 Work register
R9 EQU 9 Work register
R15 EQU 15 Entry point address
*
WTO 'ADLABIV4: Calling imported function dllfunc',ROUTCDE=11
*
CEEPCALL dllfunc,MF=(E,)
*
WTO 'ADLABIV4: Getting address of imported var DllVar', X
ROUTCDE=11
*
CEEPLDA DllVar,REG=9
*
* Set value of imported variable to 789
*
LA R8,789
ST R8,0(,R9)
*
WTO 'ADLABIV4: Done.',ROUTCDE=11
*
SR R15,R15
RETURN DS 0H
CEETERM RC=(R15),MODIFIER=0
*
*
CEEPDDA DllVar,SCOPE=IMPORT
DLLPPA CEEPPA
LTORG
CEEDSA
CEECAA
END DLLAPPL
See Figure 1 for a summary of the processing steps required for the application and related DLLs.