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.

To use a load-on-call DLL in your simple DLL application, perform the following steps:

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):

Figure 1. COBOL DLL application calling a COBOL DLL
       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
           .
The following code fragment illustrates how an Assembler routine can use the ADLLBEV2 DLL described in Writing your Language Environment-conforming assembler DLL code. Assemble and bind with the definition side-deck provided with the ADLLBEV2 DLL.
Figure 2. Assembler DLL application calling an assembler DLL
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.