Document revision date: 5 July 2000

## Compaq DCE for OpenVMS VAX and OpenVMS Alpha
Product Guide

Previous | Contents | Index

## Chapter 13
Development of Distributed Applications with FORTRAN

This chapter explains how to use FORTRAN in the development of distributed applications that make remote procedure calls.

This chapter provides the following information:

- Interoperability and portability issues as they relate to applications written in FORTRAN
- A comprehensive example that introduces and illustrates several concepts
- General reference information about FORTRAN and remote procedure calls, including a discussion about restrictions

## 13.1 Interoperability and Portability

In general, an application you create in the Compaq DCE RPC environment will interoperate with other DCE RPC applications and will port to other DCE platforms if it complies with the appropriate programming language standards. More specifically:

- Any client that you have correctly created in a Compaq DCE RPC environment to use a DCE interface expressed in an IDL file will interoperate with any DCE RPC server that supports the interface.
- Any server that you have correctly created in a Compaq DCE RPC environment to use a DCE interface expressed in an IDL file will interoperate with any DCE RPC client that makes calls on the interface.

Typically, applications created in the DCE RPC environment are written in the C programming language. However, if you use the FORTRAN support in the Compaq DCE for OpenVMS VAX and OpenVMS Alpha software, the application will be subject to the following portability constraint:

- Compaq DCE RPC applications that contain code written in FORTRAN in an OpenVMS environment and that use a DCE interface expressed in an IDL file will interoperate with any corresponding DCE server or DCE client. However, you can port these applications only to other Compaq DCE environments.

## 13.2 Remote Procedure Calls Using FORTRAN --- Example

The OpenVMS DCE IDL compiler provides similar support for applications written in FORTRAN as that provided for applications written in C. That is, you can write an RPC client in FORTRAN or you can write one or more manager routines in the server side of the application in FORTRAN. If you are unfamiliar with the tasks involved in developing an RPC application, see the chapter about application building in the OSF DCE Application Development Guide.

The FORTRAN support consists of stubs that use FORTRAN linkage conventions and a file that contains FORTRAN definitions of the constants and types declared in an interface definition. (These conventions and definitions are explained in Section 13.3)

The following sections present a comprehensive example that demonstrates how you can create the various parts of a simple, distributed payroll application using FORTRAN. The important features of this example are as follows:

- The example client application reads time-card information, passes it to a server that calculates wages, and prints the results.
- Both the client and the portion of the server that calculates gross pay (the manager routine) are written in FORTRAN.
- The initialization portion of the server application is written in C.

### 13.2.1 Where to Obtain the Example Application Files

All of the example application files referenced in this chapter are located in the following directory in your kit:

SYS$COMMON:[SYSHLP.EXAMPLES.DCE.RPC.PAYROLL]

Table 13-1 lists application files that normally would be created by the programmer for an application. To demonstrate application building, these application files are provided for you in the software kit. Table 13_2 in Section 13.2.3 lists the files generated by the IDL compiler for the example application.

Before you execute any of the example compilations, builds, or run commands in this chapter, copy all of the files listed in Table 13-1 to an empty directory. Compaq recommends that you read the file named PAYROLL.README in the same subdirectory. Then build and run the examples.

Table 13-1 Example Files Created by the Programmer
Filename | File Description
--- | ---
PAYROLL.IDL | The interface definition file that contains the application programming interface (API) to the remote procedure call `calculate_pay()` .
PRINT_PAY.FOR | The FORTRAN source file for the client side of the application.
SERVER.C | The FORTRAN source file that contains the initialization code for the server side of the application.
MANAGER.FOR | The FORTRAN source file for the server side of the application.
PAYROLL.COM | The command file that builds and runs the example application.
PAYROLL.DAT | The data input file for the example application.

The programs, procedures, and data files in the payroll example should be the same in this chapter and in the specified subdirectory that came with your Compaq DCE for OpenVMS VAX or OpenVMS Alpha software. For example, file PAYROLL.IDL as it appears in Section 13.2.2 should be identical to the following file:

SYS$COMMON:[SYSHLP.EXAMPLES.DCE.RPC.PAYROLL]PAYROLL.IDL

For all of the example files, if there is a difference between the file as shown in this chapter and the file in the subdirectory, assume that the file in the subdirectory is the correct one.

### 13.2.2 The Interface File and Data File (PAYROLL.IDL and PAYROLL.DAT)

The following interface, named PAYROLL.IDL, is part of the example application. The name of the remote procedure in the interface is `calculate_pay()` . The interface does not indicate that this procedure is written in FORTRAN.

    /*
    **               Copyright (c) 1999 by
    **      Compaq Computer Corporation, Houston, Texas.
    **
    */

    [
    uuid(d1b14181-6543-11ca-ba11-08002b17908e),
    version(1.0)
    ]
    interface payroll
    {
        const long string_data_len = 7;

        typedef struct {
            [string] char grade[string_data_len + 1];
        /* Storage for a string must include space for a null terminator */
            short   regular_hours;
            short   overtime_hours;
        } timecard;

        void calculate_pay(
            [in] timecard cards[1..7],
            [out] long *pay
        );
    }

The next part of the example is the data file PAYROLL.DAT, which the client side of the application reads. The facts about each employee appear in eight records. The first record contains the employee's name (40 characters) and grade (7 characters). Records two to eight contain the number of regular hours and overtime hours worked on Monday to Sunday. Note that the time card structure defined in PAYROLL.IDL does not specify the employee's name in the data going to the remote procedure.

    Jerry Harrison                          FOREMAN
     8 1
     8 1
     8 2
     8 2
     8 1
     0 4
     0 0
    Tony Hardiman                           WORKER
     8 0
     8 0
     8 0
     8 2
     8 0
     0 4
     0 0
    Mary Flynn                              WORKER
     8 1
     8 1
     8 2
     8 0
     8 1
     0 4
     0 0

### 13.2.3 Compiling the Interface with the IDL Compiler

To compile an RPC interface, you must invoke the IDL compiler. To compile an RPC interface for a FORTRAN application, you must select the following IDL options:

- Option `-lang fortran` (universal syntax) or the qualifier /LANGUAGE=FORTRAN (OpenVMS DCL syntax). This option specifies FORTRAN as the source code language.
- Option `-standard extended` (universal syntax) or the qualifier /STANDARD=EXTENDED (OpenVMS DCL syntax). This option enables features beyond those available in OSF DCE Version 1.0.3.

The following example commands illustrate how to invoke the IDL compiler using the universal and DCL interfaces, respectively, to compile the sample FORTRAN application interface:

    $ idl payroll.idl -lang fortran -standard extended
    $ IDL/LANGUAGE=FORTRAN/STANDARD=EXTENDED
    PAYROLL.IDL

As a result of this command, the IDL compiler generates the files listed in Table 13-2.

Table 13-2 Example Files Created by IDL
Filename | File Description
--- | ---
PAYROLL_CSTUB.OBJ | The stub file generated by the IDL compiler for the client side of the application.
PAYROLL_SSTUB.OBJ | The stub file generated by the IDL compiler for the server side of the application.
PAYROLL.FOR | An include file that emulates the C language header file (.H) and that documents the valid syntax for subroutine calls that are used in the FORTRAN source files. This file will be called out by PAYROLL.COM and linked with the other application files because it refers to constants and types defined in the interface definition.
PAYROLL.FOR_H | A file generated by the IDL compiler that is used to build the stub files.

File PAYROLL.FOR, as generated by the IDL compiler, is next.

    C     Generated by IDL compiler version Compaq DCE Vn.n.n-n
    C
    C     The following statements must appear in application code
    C     INCLUDE 'NBASE.FOR'

          INTEGER*4 STRING_DATA_LEN
          PARAMETER (STRING_DATA_LEN=7)

          STRUCTURE /TIMECARD/
              CHARACTER*8 GRADE
              INTEGER*2 REGULAR_HOURS
              INTEGER*2 OVERTIME_HOURS
          END STRUCTURE

    C      SUBROUTINE CALCULATE_PAY(CARDS, PAY)
    C      RECORD /TIMECARD/ CARDS(7)
    C      INTEGER*4 PAY

As you read this chapter, it is important to remember that the interface defined in file PAYROLL.IDL appears as FORTRAN statements in file PAYROLL.FOR. As a specific instance, consider the overtime hours field. Its definition appears in PAYROLL.IDL as the statement `short overtime_hours` , and in PAYROLL.FOR as the statement `INTEGER*2 OVERTIME_HOURS` . The overtime hours data in file PAYROLL.DAT is read into a data item of this type.

### 13.2.4 The Client Application Code for the Interface (PRINT_PAY.FOR)

Suppose that the directory in which the interface was compiled also contains file PRINT_PAY.FOR. This is the source file for the client side of the distributed application. Its contents follow.

    C This is the client side of a payroll application that
    C    uses remote procedure calls.
    C
            PROGRAM PRINT_PAY
            INCLUDE 'PAYROLL.FOR'    ! Created by the IDL compiler from
                                     !    file PAYROLL.IDL.

    C COPYRIGHT (C) 1999 BY COMPAQ COMPUTER CORPORATION.  HOUSTON, TEXAS.

    C       The structure of a time card is described in the included file.
            RECORD /TIMECARD/ CARDS(7)
            CHARACTER*40 NAME
            CHARACTER*8  GRADE
            INTEGER*4 PAY
            INTEGER*4 I
    C
    C Read eight records for the current employee.
       10   READ (4, 9000, END=100) NAME, GRADE  ! First record
     9000   FORMAT (A40, A8)
            DO 20 I = 1, 7   ! Second through eighth records
               READ (4,9010) CARDS(I).REGULAR_HOURS, CARDS(I).OVERTIME_HOURS
     9010      FORMAT (I2, I2)
               CARDS(I).GRADE = GRADE
       20   CONTINUE
    C
    C Call remote procedure CALCULATE_PAY to calculate the gross pay.
            CALL CALCULATE_PAY (CARDS, PAY)
    C Display the current employee's name and gross pay.
            WRITE  (6, 9020) NAME,     PAY
     9020   FORMAT (1X,      A40,  1X, I4  )
            GO TO 10
    C
      100   STOP
    C
            END

To compile and link the client program PRINT_PAY.FOR, which at runtime makes remote procedure calls to a server that supports the payroll interface, use the following DCL commands. After you enter the LINK command, press <CTRL/Z>.

    $ FORTRAN PRINT_PAY.FOR
    $ LINK PRINT_PAY, PAYROLL_CSTUB, DCE:DCE/OPT, DCE:DCE_VAXC/OPT

Instead of using these two commands directly to build the client part of the application, you can invoke procedure PAYROLL.COM to build the entire application. See Section 13.2.8 for information about building and running this example.

This program reads its data from FORTRAN logical unit 4. A DCL command in procedure PAYROLL.COM defines the logical unit.

### 13.2.5 The Server Initialization File (SERVER.C)

Because all programming interfaces to the RPC runtime are specified in C, you must write the code that sets up the server in C. In this example, the server setup code (also called the initialization code) is in file SERVER.C.

This file is shown next. Both SERVER.C and PAYROLL.COM (shown in this section and in Section 13.2.8, respectively) contain the literal `FORTRAN_payroll_mynode` . Do not substitute a node name for `mynode` . The code in SERVER.C always exports its bindings using the entry name ".:/FORTRAN_payroll_mynode".

    /* This is program SERVER.C that sets up the server for the application
       code whose origin is FORTRAN subroutine CALCULATE.PAY.               */

    /*
    ** Copyright (c) 1999 by
    **     Compaq Computer Corporation.  Houston, Texas.
    **
    */

    #include <STDIO.H>
    #include <FILE.H>
    #include <DCE/DCE_ERROR.H>
    #include "payroll.for_h"  /* The IDL compiler created this file from
                                 file PAYROLL.IDL.                       */

    static char error_buf[dce_c_error_string_len+1];
    static char *error_text(st)
        error_status_t st;
    {
        error_status_t rst;
        dce_error_inq_text(st, error_buf, &rst);
        return error_buf;
    }

    main()
    {
        error_status_t st;
        rpc_binding_vector_p_t bvec;

        /* Register all supported protocol sequences with the runtime. */
        rpc_server_use_all_protseqs(
            rpc_c_protseq_max_calls_default,
            &st
        );
        if (st != error_status_ok)
        {
         fprintf(stderr, "Can't use protocol sequence - %s\\n", error_text(st));
            exit(1);
        }

        /* Register the server interface with the runtime.                 */
        rpc_server_register_if(
            payroll_v1_0_s_ifspec,  /* From the IDL compiler;              */
                                    /* "v1_0" comes from the statement     */
                                    /* "version(1.0)" in file PAYROLL.IDL. */
            NULL,
            NULL,
            &st
        );
        if (st != error_status_ok)
        {
            printf("Can't register interface - %s\\n", error_text(st));
            exit(1);
        }

        /* Get the address of a vector of server binding handles.  The
           call to routine rpc_server_use_all_protseqs() directed the
           runtime to create the binding handles.                      */
        rpc_server_inq_bindings(&bvec, &st);
        if (st != error_status_ok)
        {
            printf("Can't inquire bindings - %s\\n", error_text(st));
            exit(1);
        }

        /* Place server address information into the local endpoint map. */
        rpc_ep_register(
            payroll_v1_0_s_ifspec,
            bvec,
            NULL,
            (idl_char*)"FORTRAN Payroll Test Server",
            &st
        );
        if (st != error_status_ok)
        {
            printf("Can't register ep - %s\\n", error_text(st));
        }

        /* Place server address information into the name service database. */
        rpc_ns_binding_export(
            rpc_c_ns_syntax_default,
            (idl_char*)".:/FORTRAN_payroll_mynode",
            payroll_v1_0_s_ifspec,
            bvec,
            NULL,
            &st
        );
        if (st != error_status_ok)
        {
            printf("Can't export to name service - %s\\n", error_text(st));
        }

        /* Tell the runtime to listen for remote procedure calls.
           Also, FORTRAN cannot support multiple threads of execution. */
        rpc_server_listen((int)1, &st);
        if (st != error_status_ok)
            fprintf(stderr, "Error listening: %s\\n", error_text(st));

    }

### 13.2.6 The Server Application Code for the Interface (MANAGER.FOR)

The server application code, written in FORTRAN, is declared in file PAYROLL.IDL as `calculate_pay()` . The file MANAGER.FOR provides some additional application code for the server and it contains subroutine CALCULATE_PAY as follows:

            SUBROUTINE CALCULATE_PAY(CARDS, PAY)
            INCLUDE 'PAYROLL.FOR'    ! Created by the IDL compiler from
                                     !    file PAYROLL.IDL.

    C
    C COPYRIGHT (C) 1999 BY COMPAQ COMPUTER CORPORATION.  HOUSTON, TEXAS.

    C       The structure of a time card is described in included file PAYROLL.FOR.
            RECORD /TIMECARD/ CARDS(7)
            INTEGER*4 PAY
            INTEGER*4 I

            PAY = 0
            DO 10 I = 1, 7
    C     The basic hourly wage is $6.00.
                PAY = PAY + 6 * CARDS(I).REGULAR_HOURS
    C     The following comparison does not include last character of GRADE,
    C        because it arrives as a null terminator.
                IF (CARDS(I).GRADE(1:STRING_DATA_LEN) .EQ. 'FOREMAN') THEN
    C         The overtime hourly wage for a foreman is $12.00.
                    PAY = PAY + 12 * CARDS(I).OVERTIME_HOURS
                ELSE
    C         The overtime hourly wage for a worker is $9.00.
                    PAY = PAY +  9 * CARDS(I).OVERTIME_HOURS
                END IF
       10   CONTINUE

            RETURN
            END

To create the file SERVER.EXE, which at runtime responds to remote procedure calls from a client that supports the payroll interface, use the following DCL commands. After you enter the LINK command, press <CTRL/Z>.

    $ CC SERVER
    $ FORTRAN MANAGER
    $ LINK SERVER, MANAGER, PAYROLL_SSTUB, DCE:DCE/OPT, DCE:DCE_VAXC/OPT

Instead of using these commands directly to build the server part of the application, you can invoke procedure PAYROLL.COM to build the entire application (see Section 13.2.8).

### 13.2.7 Client and Server Bindings

To make remote procedure calls, client applications must be bound to server applications. This is illustrated in the client program PRINT_PAY.FOR shown in Section 13.2.4. The source code in the client program uses the default `[auto_handle]` binding, which is enabled by the following source code:

    C Call remote procedure CALCULATE_PAY to calculate the gross pay.
            CALL CALCULATE_PAY (CARDS, PAY)

When you invoke procedure PAYROLL.COM (shown in Section 13.2.8), it displays a message about assuming `[auto_handle]` .

For more information about client and server bindings, see the chapter on basic DCE RPC runtime operations in the OSF DCE Application Development Guide.

### 13.2.8 Building and Running the Example (PAYROLL.COM)

You can build, run, or both build and run the payroll example by using command file PAYROLL.COM. Its contents follow.

    $!
    $! This is file PAYROLL.COM to build, run, or both build and run
    $!     the distributed payroll application.
    $!

    $!                      COPYRIGHT (C) 1999 BY
    $!                 COMPAQ COMPUTER CORPORATION.  HOUSTON, TEXAS.
    $!                      ALL RIGHTS RESERVED.

    $!
    $! THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
    $! ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE INCLUSION
    $! OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR ANY OTHER COPIES
    $! THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY OTHER
    $! PERSON.  NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERRED.
    $!
    $! THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND

    $! SHOULD NOT BE CONSTRUED AS A COMMITMENT BY COMPAQ COMPUTER CORPORATION.

    $!
    $! COMPAQ ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
    $! SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY COMPAQ.
    $!
    $!
    $! @PAYROLL        is the default -- to build and run.
    $! @PAYROLL BUILD  does only the build.
    $! @PAYROLL RUN    does only a sample run.
    $!
    $ SAY := WRITE SYS$OUTPUT
    $ IF P1 .eqs. "RUN" then goto DO_RUN
    $!
    $! Build the application.
    $ SAY "Building..."
    $
    $! Enable the universal IDL command interface
    $ idl := $sys$system:dce$idl.exe
    $
    $! Compile the interface definition
    $! -keep all is used to keep the IDL output for training purposes
    $ idl PAYROLL.IDL -keep all -trace all -trace log_manager -lang fortran -
                      -standard extended
    $
    $! Compile the client application files
    $ FORTRAN PRINT_PAY
    $
    $! Link the client application
    $ LINK PRINT_PAY,PAYROLL_CSTUB, DCE:DCE/OPT, DCE:DCE_VAXC/OPT
    $
    $! Compile the server application files
    $ CC SERVER
    $ FORTRAN MANAGER
    $
    $! Link the server application
    $ LINK SERVER,MANAGER,PAYROLL_SSTUB,DCE:DCE/OPT,DCE:DCE_VAXC/OPT
    $ IF P1 .eqs. "BUILD" then exit
    $
    $DO_RUN:
    $! Run the application.
    $ SAY "Activating server image..."
    $ DEFINE/NOLOG RPC_DEFAULT_ENTRY ".:/FORTRAN_payroll_mynode"
    $  SPAWN/NOWAIT/INPUT=NL:/OUTPUT=SERVER.LOG/PROCESS=FORTRAN_SERVER -
              RUN SERVER
    $ WAIT 00:00:10     ! Allow 10 seconds for the server to start.
    $ DEFINE/NOLOG FOR004 PAYROLL.DAT
    $ SAY "Activating client image..."
    $  RUN PRINT_PAY
    $ SAY "Deleting server process..."
    $ STOP FORTRAN_SERVER
    $ SAY "End of sample application"

If you prefer to use OpenVMS DCL syntax for the command to the IDL compiler, then one way to modify file PAYROLL.COM follows.

Consider these seven lines:

    $! Enable the universal IDL command interface
    $ idl := $sys$system:dce$idl.exe
    $
    $! Compile the interface definition
    $! -keep all is used to keep the IDL output for training purposes
    $ idl PAYROLL.IDL -keep all -trace all -trace log_manager -lang fortran -
                      -standard extended

Change the second, third, sixth, and seventh lines to comments by adding a "$!" at the beginning of each line (or delete all seven lines). Then, add the following three lines before the two lines:

    $
    $! Compile the client application files

    $! Use OpenVMS DCL syntax for the command to the IDL compiler.
    $ IDL/KEEP=ALL/TRACE=(EVENTS=ALL,LOG_MANAGER)/LANGUAGE=FORTRAN -
         /STANDARD=EXTENDED PAYROLL.IDL

This modification works only if you do not otherwise have the symbol IDL defined.

Previous | Next | Contents | Index

| privacy and legal statement |
6532_DCE_PG_PRO_009.HTML