Compaq COBOL
User Manual


Previous Contents Index

1.3.3.3 Specifying Modules Other than Compaq COBOL Modules

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:

  1. Is invoked before the Compaq COBOL LIB$INITIALIZE routine (COB_NAME_START) and
  2. Calls a Compaq COBOL program that contains CALL by data name, extended ACCEPT, or extended DISPLAY statements.

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:

  1. Create the main program used to call the subprogram (as a shareable image).
  2. Create the subprogram.
  3. Link the shareable image program using the /SHARE qualifier and including the options file containing the symbol vector in the LINK command as an input file. (Refer to Using Symbol Vectors with Shareable Images in this section for information about declaring universal symbols using a symbol vector.)
  4. Define a logical name to point to your shareable image.
  5. Link the main program with the 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:

1.3.4 Running a Compaq COBOL Program

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:

1.3.4.1 Accessing Command-Line Arguments at Run Time

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.

Note

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