Previous | Contents | Index |
When you link Compaq COBOL modules with other modules, your application will not work correctly if a non Compaq COBOL module contains a LIB$INITIALIZE routine that:
Compaq COBOL uses the LIB$INITIALIZE routine, COB_NAME_START, to initialize the run-time environment for the CALL by data name and extended ACCEPT and DISPLAY statements. Therefore, the COB_NAME_START routine must be invoked before any CALL, ACCEPT, or DISPLAY statements are performed.
The order in which LIB$INITIALIZE routines are invoked is determined during the link and is shown in the image map. To ensure that the Compaq COBOL LIB$INITIALIZE routine is invoked first, change your link command to the following:
$ LINK/EXE=name SYS$SHARE:STARLET/INCL=COB_NAME_START,your_modules... |
See Appendix B for information on a problem with LIB$INITIALIZE when
you call a C program.
1.3.3.4 Specifying Object Module Libraries
Linking against object modules allows your program to access data and routines outside of your compilation units. You can create your own object module libraries or they can be supplied by the system.
User-Created Object Module Libraries
You can make program modules accessible to other programmers by storing them in object module libraries. To link modules contained in an object module library, use the /INCLUDE qualifier with the LINK command2 and specify the modules you want to link. The following example links the subprogram modules EGGPLANT, TOMATO, BROCCOLI, and ONION (contained in the VEGETABLES library) with the main program module GARDEN:
$ LINK GARDEN, VEGETABLES/INCLUDE=(EGGPLANT,TOMATO,BROCCOLI,ONION) |
An object module library also contains a symbol table with the names of the global symbols in the library, and the names of the modules in which the symbols are defined. You specify the name of the object module library containing these symbol definitions with the /LIBRARY qualifier. When you use the /LIBRARY qualifier during a linking operation, the linker searches the specified library for all unresolved references found in the included modules during compilation.
The following example uses the library RACQUETS to resolve undefined symbols in the BADMINTON, TENNIS, and RACQUETBALL libraries:
$ LINK BADMINTON, TENNIS, RACQUETBALL, RACQUETS/LIBRARY |
For more information about the /INCLUDE and /LIBRARY qualifiers, invoke the online HELP facility for the LINK command at the DCL prompt or refer to the OpenVMS Linker Utility Manual.
You can define one or more of your private object module libraries as default user libraries. The following section describes how to accomplish this using the DEFINE command.
Defining Default User Object Module Libraries
You can define one or more of your private object module libraries as your default user libraries using the DCL DEFINE command, as in the following example:
$ DEFINE LNK$LIBRARY DEFLIB |
The linker searches default user libraries for unresolved references after it searches modules and libraries specified in the LINK command.
In this example, LNK$LIBRARY is a logical name and DEFLIB is the name of an object module library (having the file type OLB) that you want the linker to search automatically in all subsequent link operations.
You can establish any object module library as a default user library by creating a logical name for the library. The logical names you must use are LNK$LIBRARY (as in the preceding example), LNK$LIBRARY_1, LNK$LIBRARY_2, and so on, to LNK$LIBRARY_999. When more than one of these logical names exists when a LINK command executes, the linker searches them in numeric order beginning with LNK$LIBRARY.
When one or more logical names exist for default user libraries, the linker uses the following search order to resolve references:
This search sequence occurs for each reference that remains unresolved.
System-Supplied Object Module Libraries
All Compaq COBOL programs reference system-supplied object module libraries when they are linked. These libraries contain routines that provide I/O and other system functions. Additionally, you can use your own libraries to provide application-specific object modules.
To use the contents of an object module library, you must do the following:
To specify that a linker input file is a library file, use the /LIBRARY qualifier. This qualifier causes the linker to search for a file with the name you specify and the default file type .OLB. If you specify a file that the linker cannot locate, a fatal error occurs and linking terminates.
The sections that follow describe the order in which the linker searches libraries that you specify explicitly, default user libraries, and system libraries.
For more information about object module libraries, see the OpenVMS Linker Utility Manual.
Defining the Search Order for Libraries
When you specify libraries as input for the linker, you can specify as many as you want; there is no practical limit. More than one library can contain a definition for the same module name. The linker uses the following conventions to search libraries specified in the command string:
For example:
$ LINK METRIC,DEFLIB/LIBRARY,APPLIC |
The library DEFLIB will be searched only for unresolved references in the object module METRIC. It is not searched to resolve references in the object module APPLIC. However, this command can also be entered as follows:
$ LINK METRIC,APPLIC,DEFLIB/LIBRARY |
In this case, DEFLIB.OLB is searched for all references that are not
resolved between METRIC and APPLIC. After the linker has searched all
libraries specified in the command, it searches default user libraries,
if any, and then the default system libraries.
1.3.3.5 Creating Shareable Images
You can create Compaq COBOL programs as shareable images by using the LINK qualifier /SHARE. A shareable image is a single copy of a program that can be shared by many users or applications. Using shareable images provides the following benefits:
The following list describes one way to create and install a Compaq COBOL program as a shareable image:
Once you have completed these steps, you can run the main program to access the subprogram installed as a shareable image.
See the OpenVMS Linker Utility Manual and the Guide to Creating OpenVMS Modular Procedures for more information about shareable images.
The following sample programs and command procedure provide an example of how to create, link, and install a subprogram as a shareable image, as described in the preceding steps.
Example 1-2 shows the main program CALLER.COB and the two subprograms (SUBSHR1.COB and SUBSHR2.COB). Only the subprograms are installed as shareable images.
Example 1-2 Main Program and Subprograms |
---|
* CALLER.COB IDENTIFICATION DIVISION. PROGRAM-ID. CALLER. ****************************************************************** * This program calls a subprogram installed as a shareable image.* ****************************************************************** PROCEDURE DIVISION. 0. CALL "SUBSHR1" ON EXCEPTION DISPLAY "First CALL failed. Program aborted." END-CALL. STOP RUN. END PROGRAM CALLER. * SUBSHR1.COB IDENTIFICATION DIVISION. PROGRAM-ID. SUBSHR1. ****************************************************************** * This program is linked as a shareable image. When it is called,* * it calls another program installed as a shareable image. * ****************************************************************** PROCEDURE DIVISION. 0. DISPLAY "Call to SUBSHR1 successful. Calling SUBSHR2.". CALL "SUBSHR2" ON EXCEPTION DISPLAY "Second call failed. Control returned to CALLER." END-CALL. END PROGRAM SUBSHR1. * SUBSHR2.COB IDENTIFICATION DIVISION. PROGRAM-ID. SUBSHR2. **************************************************************** * This program is linked as a shareable image and is called by * * another shareable image. * **************************************************************** PROCEDURE DIVISION. 0. DISPLAY "Call to SUBSHR2 successful!". END PROGRAM SUBSHR2. |
Example 1-3 shows a command procedure that compiles, links, and installs the sample programs in Example 1-2.
Example 1-3 Command Procedure to Link a Program as a Shareable Image |
---|
$! Create the main program and subprograms to be installed as $! shareable images. In this example CALLER.COB is the main program. $! SUBSHR1.COB and SUBSHR2.COB are the subprograms to be installed $! as shareable images. $! $! Compile the main program and subprograms. $! $ COBOL CALLER.COB $ COBOL SUBSHR1.COB $ COBOL SUBSHR2.COB $! $! Create an options file containing all the universal symbols $! (entry points and other data symbols) for the subprograms. $! $ COPY SYS$INPUT OPTIONS1.OPT $ DECK SYMBOL_VECTOR=(SUBSHR1=PROCEDURE,SUBSHR2=PROCEDURE) $ EOD $! $! Link the subprograms using the /SHARE qualifier to the $! shareable library and the options file. For more information $! on options files, refer to the OpenVMS Linker Utility Manual. $! $ LINK/SHARE=MYSHRLIB SUBSHR1,SUBSHR2,OPTIONS1/OPT $! $! Assign a logical name for the shareable images. $! $ ASSIGN DEVICE:[DIRECTORY]MYSHRLIB.EXE MYSHRLIB $! $! Create a second options file to map the main program to the $! shareable image library. $! $ COPY SYS$INPUT OPTIONS2.OPT $ DECK MYSHRLIB/SHAREABLE $ EOD $! $! Link the main program with the shareable image subprograms $! through the options file. $! $ LINK CALLER,OPTIONS2/OPT $! $! Now you can run the main program. |
Using Symbol Vectors with Shareable Images
To make symbols in the shareable image available for other modules to link against, you must declare the symbols as universal. You declare universal symbols by creating a symbol vector. You create a symbol vector by specifying the SYMBOL_VECTOR=option clause in a linker options file. List all of the symbols you want to be universal in the order in which you want them to appear in the symbol vector.
If you use symbol vectors, you can modify the contents of shareable images and avoid relinking user programs bound to the shareable image when you modify the image. Once you have created the symbol vector, you can install the subprograms and link the main program to the shareable library. Symbol vectors, if used according to the coding conventions, can also provide upward compatibility.
For more information about symbol vectors, refer to the OpenVMS Linker Utility Manual.
1.3.3.6 Interpreting Messages from the Linker
If the linker detects any errors while linking object modules, it displays system messages indicating their cause and severity. If any error or fatal error conditions occur, the linker does not produce an image file. See the OpenVMS Linker Utility Manual for complete information about the format of linker options.
Linker messages are self-explanatory; you do not usually need additional information to determine the specific error.
Common Linking Errors to Avoid
The following are some common errors to avoid when linking COBOL programs:
$ LINK OCEAN,REEF,SHELLS |
%LINK-W-NUDFSYMS, 1 undefined symbol %LINK-I-UDFSYMS, SEAWEED %LINK-W-USEUNDEF, undefined symbol SEAWEED referenced in psect $CODE offset %X0000000C in module OCEAN file DEVICE$:[COBOL.EXAMPLES]PROG.OBJ;1 %LINK-W-USEUNDEF, undefined symbol SEAWEED referenced in psect $CODE offset %X00000021 in module OCEAN file DEVICE$:[COBOL.EXAMPLES]PROG.OBJ;1 |
After you compile and link your program, use the RUN command to execute it. In its simplest form the RUN command has the following format:
$ RUN myprog |
In the preceding example MYPROG.EXE is the file specification of the image you want to run. If you omit the file type from the file specification, the system automatically provides a default value. The default file type is .EXE. If you omit a path specification, the system will expect MYPROG.EXE to be in the current directory.
When you run your application it makes calls to the Compaq COBOL Run-Time Library (RTL) installed on your system. If your application is run on a system other than the one where the application was compiled, there are two requirements that must be met:
Your Compaq COBOL programs can read command-line arguments and access (read and write) system logicals. Command-line arguments enable you to provide information to a program at run time. Your program provides the logic to parse the command line, identify command-line options, and act upon them. For example, you might develop a program named MYPROG that will extract a given amount of data from a specified file, where both the number of records to read and the file name are highly dynamic, changing for each activation of your program. In this case your program would contain code that reads a command-line argument for the number of records to read and a second argument for the file specification.
To run the program with command-line arguments, you must define it as a foreign command, as follows:
$ MYPROG :== "$device:[dir]MYPROG.EXE" |
When you use this command, you will replace device and dir with the valid device:[dir] names where MYPROG.EXE is located. Your program execution command could then look like the following:
$ MYPROG 1028 POWERS.DAT |
In this hypothetical case, the program MYPROG would read 1,028 records from the file POWERS.DAT.
Multiple command-line arguments are delimited by spaces, as shown in the preceding example. If an argument itself contains spaces, enclose that argument in quotation marks (" ") as follows:
$ myprog2 "all of this is argument 1" argument2 |
In this example the returned value of argument1 will be the entire string "all of this is argument1", and argument2 will be simply "argument2".
You provide definitions for the command-line arguments with the
SPECIAL-NAMES paragraph in your program's Environment Division, and
include ACCEPT and DISPLAY statements in the Procedure Division to
parse the command line and access the arguments. Detailed information
about command-line argument capability is in the ACCEPT and DISPLAY
sections in the Compaq COBOL Reference Manual.
1.3.4.2 Accessing System Logicals at Run Time
You can read and write system logicals at run time through your Compaq COBOL program.
Example 1-4 allows the user to specify a file specification by putting the directory in the value of the logical COBOLPATH and the file name in a command-line argument.
Example 1-4 Accessing Logicals and Command-Line Arguments |
---|
IDENTIFICATION DIVISION. PROGRAM-ID. EXAMPLE. ENVIRONMENT DIVISION. CONFIGURATION SECTION. SPECIAL-NAMES. SYSERR IS STANDARD-ERROR ENVIRONMENT-NAME IS NAME-OF-LOGICAL ENVIRONMENT-VALUE IS LOGICAL-VALUE ARGUMENT-NUMBER IS POS-OF-COMMAND-LINE-ARGUMENT ARGUMENT-VALUE IS COMMAND-LINE-ARGUMENT. DATA DIVISION. WORKING-STORAGE SECTION. 01 howmany-records PIC 9(5). 01 env-dir PIC x(50). 01 file-name PIC x(50). 01 file-spec PIC x(100). PROCEDURE DIVISION. BEGIN. ACCEPT howmany-records FROM COMMAND-LINE-ARGUMENT ON EXCEPTION DISPLAY "No arguments specified" UPON STANDARD-ERROR STOP RUN END-ACCEPT. DISPLAY "COBOLPATH" UPON NAME-OF-LOGICAL. ACCEPT env-dir FROM LOGICAL-VALUE ON EXCEPTION DISPLAY "Logical COBOLPATH is not set" UPON STANDARD-ERROR END-DISPLAY NOT ON EXCEPTION ACCEPT file-name FROM COMMAND-LINE-ARGUMENT ON EXCEPTION DISPLAY "Attempt to read beyond end of command line" UPON STANDARD-ERROR END-DISPLAY NOT ON EXCEPTION STRING env-dir file-name delimited by " " into file-spec DISPLAY "Would have read " howmany-records " records from " file-spec END-ACCEPT END-ACCEPT. |
Example 1-4 assumes that the logical COBOLPATH is set as follows:
$ define COBOLPATH MYDEV:[MYDIR] |
When you execute the following command line:
$ MYPROG 1028 powers.dat |
The following will result:
For additional information, see the ACCEPT and DISPLAY statements in the Compaq COBOL Reference Manual.
2 The /INCLUDE qualifier on the LINK command is not to be confused with the /INCLUDE qualifier on the COBOL compile command, which specifies a search list for COPY files. |
Previous | Next | Contents | Index |