Dynamic Link Library (DLL) processing

The binder supports the code that is generated by C++, and by C with the DLL compiler option, as well as code that is generated by C and C++ with the XPLINK option. Code generated with the XPLINK compiler option, like code generated by C++ and code generated by C with the DLL option, is always DLL-enabled (that is, references can be satisfied by IMPORT control statements). The binder option DYNAM(DLL) controls DLL processing. You must specify DYNAM(DLL) if the program object is to be a DLL, or if it contains DLL-type references. This topic assumes that you specified the DYNAM(DLL) option. See z/OS MVS Program Management: User's Guide and Reference for more information on the DYNAM(DLL) binder option. You must also specify CASE(MIXED) in order to preserve the case sensitivity of symbols on IMPORT control statements.

If you are building an application that imports symbol definitions from a DLL, you must include an IMPORT control statement for each symbol to which your application expects to dynamically link. Typically, the input to your bind step for your application should include the definition side-deck of IMPORT control statements that the binder generated when the DLL was built. For compatibility, the binder accepts definition side-decks of IMPORT control statements that the Language Environment® Prelinker generated. To use the definition side-decks that are distributed with IBM® Class libraries, you must specify the binder option CASE(MIXED).

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 class 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 linkage blocks (descriptors) for the importer in C_WSA during program execution.

The binder builds tables of imported and exported symbols in the class B_IMPEXP, section IEWBCIE. This element contains the necessary information about imported and exported symbols to support runtime library dynamic linking and loading.

Statically bound functions

For each DLL-referenced function, the binder will generate a function linkage block (descriptor) of the same name as a part in the class C_WSA.

Some of the linkage descriptors for XPLINK code are generated by the compiler rather than the binder. Compiler-generated descriptors are not visible as named entities at bind time. For XPLINK:
  • Functions, which are referenced exclusively in the compilation unit, have descriptors which are generated by the compiler and have no visible names.
  • Functions, which are possibly referenced outside of the compilation unit (either by function pointer, or because they are exported), have descriptors which are generated by Language Environment functions when the DLL is loaded. They are not part of C_WSA. There will be a pointer to the function descriptor in C_WSA.
  • For all other DLL-referenced functions, function descriptors are generated by the binder as a part with the same name in the class C_WSA (with the exception that for NORENT compiles, the descriptor will be in B_DESCR rather than C_WSA).
All C++ code and XPLINK code generate DLL references. C code generates DLL references if you used the DLL compiler option. If a DLL reference to an external function is resolved at the end of final autocall processing, the binder generates a function linkage block of the same name in the Writable Static Area, and initializes it to point to the resolved function. If the DLL reference is to a static function, the binder generates a function linkage block with a private name, which is initialized to point to the resolved static function.

Imported variables

For each DLL-referenced external variable in C_WSA that is unresolved at the end of final autocall processing (DD SYSLIB), if a matching IMPORT control statement was read in, the variable is considered to be resolved via dynamic linking from the DLL named on the IMPORT control statement. The binder will generate a variable linkage block (descriptor) of the same name, as a part in the class C_WSA.

Imported functions

For each DLL-referenced external function that is unresolved at the end of final autocall processing, if a matching IMPORT control statement was read in, the function is considered to be resolved via dynamic linking from the DLL named on the IMPORT control statement. The binder will generate a function linkage block (descriptor) of the same name, as a part in the class C_WSA.