Building a simple DLL application
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.
- Writing your DLL application code
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.
- Compiling your DLL application code
- Compile your C source files with the following compiler options:
- DLL (not necessary if the XPLINK compiler option is specified)
- RENT
- LONGNAME
- Compile your C++ source files normally. A C++ application is always DLL code.
- Compile your COBOL source files with the following compiler options:
- DLL
- RENT
- NOEXPORTALL
- Compile your Enterprise PL/I source files with the RENT option.
- Assembler DLL Application source files must be assembled using the GOFF option.
- Compile your C source files with the following compiler options:
- Binding your DLL application code
- The binder option CASE(MIXED) is required when binding DLLs applications that use mixed-case exported names.
- The binder options RENT, DYNAM(DLL), and COMPAT(PM3) or COMPAT(CURRENT) are required.
Note: Because definition side decks in automatic library call (autocall) processing will not be resolved, you must use the INCLUDE statement.
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.