GUI ScreenIO for Windows |
You already know that a DLL is a program that can be called dynamically, right? Well, you can create a DLL that contains many entry points and make them accessible by exporting them via an import library.
This allows you to merge many subroutines into a single DLL, taking advantage of many of the best features of static and dynamically linked subroutines.
You create a DLL by telling the linker that you want a DLL instead of an EXE format executable. If you want to create a dynamically loaded subroutine "a" (A.DLL), use:
-dll -out:a.dll -def:module-definition-file.DEF |
instead of:
-out:a.exe |
The -DEF parameter tells the linker to create an import library, which allows your program to call entry points in the DLL in addition to the external name of the DLL.
Let's say that the COBOL program that is being linked as a DLL contains this source code:
IDENTIFICATION DIVISION.
|
Now, if you link this using the parameters above, the linker will create a module named A.DLL.
Question:
How can your program call the secondary entry point B? It has no way of knowing it resides in A.DLL.
Answer:
You export the symbol B.
That's what the module definition is for. It directs the linker to create an import library containing the addresses of additional entry points within the DLL, that you want to expose.
An import library is used exactly the same as an object library. You can even create an import library for a DLL and use LIB to add object modules to it, just as you would with any other object library.
You link your executable as usual, including the import library in your list of object libraries. At runtime, however, when your program attempts to call an entry that resides in a DLL, the operating system will use information from the import library that was linked into the executable to determine which DLL contains the desired entry point.
If the DLL is not loaded, the operating system will load it from disk and then pass control to it, exactly as it would if it were a statically called subroutine that was linked directly into your executable!
Neat.
If you're perceptive, it might occur to you this could be quite useful, because calls that access a DLL via an import library are coded exactly the same as static calls. This could be quite useful in a large application, because unlike statically linked modules, which are copied into every EXE and DLL that refer to them, subroutines stored in a DLL and accessed via an import library are loaded only once, and shared between all of your programs.
You tell the linker which entry points are to be placed in the import library (exported) by listing them in a module definition file, which has the extension .DEF.
The module definition file is a simple ASCII text file that contains the name of the import library, an optional description, and the names of the entry points within the DLL that you want to make available in the import library. Here's the module definition file a.def used to make the entry points A and B (which are called exports, or exported symbols) from our sample program above, available in a.lib.
LIBRARY A
|
The description is optional. So, the basic format of the link statement needed is:
LINK a.obj -dll -def:a.def ... |
Other parameters will be required, of course, depending on your compiler.
This, by the way, is how we created GS32.LIB. It's just a simple import library that exports the symbols GS32 and GSWINAPI. Here's the module definition we used to create GS32.DLL and the import library GS32.LIB distributed with GUI ScreenIO.
LIBRARY GS32
|
© 2000-2019 Norcom, all rights reserved |