OpenCOBOL 找不到 运行 程序的外部模块

OpenCOBOL can't find my external module to run the program

我正在尝试使用 OpenCobol 创建一个 COBOL 程序,该程序在进行计算时具有外部模块,然后使用 CALL 将结果返回到主程序中。但每次我尝试 运行 程序时,它都说找不到模块。我已经将我的模块从可执行文件更改为程序类型“模块”,并将模块路径添加为库路径,但到目前为止没有任何效果

这是我的主要程序代码:

   PROGRAM-ID. Project2 AS "Project2".

   ENVIRONMENT DIVISION.
   INPUT-OUTPUT SECTION.
   FILE-CONTROL.
  *****The student input file
       SELECT STUDENT-FILE-IN
           ASSIGN TO "C:\STUFILE.TXT"
           ORGANIZATION IS LINE SEQUENTIAL.

  *****The program input file
       SELECT PROGRAM-FILE-IN
           ASSIGN TO "C:\PROGRAM.TXT"
           ORGANIZATION IS LINE SEQUENTIAL.

  *****The student report output file
       SELECT STUDENT-REPORT-FILE-OUT
           ASSIGN TO "C:\REPORT.TXT"
           ORGANIZATION IS LINE SEQUENTIAL.

   DATA DIVISION.
   FILE SECTION.
  *Student input file
   FD STUDENT-FILE-IN.
   01 STUDENT-RECORD.
       05 STUDENT-NUMBER   PIC 9(6).
       05 TUITION-OWED-IN  PIC 9(4)V99.
       05 STUDENT-NAME-IN  PIC X(40).
       05 PROGRAM-OF-STUDY PIC X(5).
       05 COURSE-CODE-1    PIC X(7).
       05 COURSE-AVERAGE-1 PIC 9(3).
       05 COURSE-CODE-2    PIC X(7).
       05 COURSE-AVERAGE-2 PIC 9(3).
       05 COURSE-CODE-3    PIC X(7).
       05 COURSE-AVERAGE-3 PIC 9(3).
       05 COURSE-CODE-4    PIC X(7).
       05 COURSE-AVERAGE-4 PIC 9(3).
       05 COURSE-CODE-5    PIC X(7).
       05 COURSE-AVERAGE-5 PIC 9(3).

  *Program input file
   FD PROGRAM-FILE-IN.
   01 PROGRAM-RECORD-IN.
       05 PROGRAM-CODE-IN PIC X(5).
       05 PROGRAM-NAME-IN PIC X(20).

  *Student report output file
   FD STUDENT-REPORT-FILE-OUT.
   01 STUDENT-REPORT-RECORD-OUT PIC x(90).



   WORKING-STORAGE SECTION.
  *Table to hold program records
   01 PROGRAM-RECORD.
       05 PROGRAM-TABLE.
           10 PROGRAM-CODE PIC X(5)  OCCURS 20 TIMES.
           10 PROGRAM-NAME PIC X(20) OCCURS 20 TIMES.

  *The student report record
   01 STUDENT-REPORT-RECORD.
       05 STUDENT-NAME     PIC X(40).
       05 FILLER           PIC X(2) VALUE SPACES.
       05 PROGRAM-NAME-OUT PIC X(20).
       05 FILLER           PIC X(4) VALUE SPACES.
       05 TUITION-OWED     PIC Z,ZZ9.99.

  *A line to make the output look good
   01 HEADER-LINE.
       05 FILLER PIC X(90) VALUE ALL "-".

  *The column header
   01 COLUMN-HEADER.
       05 NAME-COLUMN PIC X(42) VALUE "NAME".
       05 AVG-COLUMN  PIC X(7)  VALUE "AVE".
       05 PROG-COLUMN PIC X(24) VALUE "PROGRAM NAME".
       05 OWED-COLUMN PIC X(12) VALUE "TUITION OWED".

   01 CONTROL-FIELDS.
       05 STUFILE-EOF-FLAG  PIC A(3).
       05 PROG-EOF-FLAG     PIC A(3).
       05 PROG-SUB          PIC 9(2).
       05 FOUND-PROG-FLAG   PIC A(3).

   01 COUNTERS.
       05 STUDENT-RECORDS-READ-CTR    PIC 9(3).
       05 STUDENT-REPORTS-WRITTEN-CTR PIC 9(3).

   01 WW-SEND-AREA.
       05 STUDENT-AVERAGE  PIC 9(3).

   01 WW-SUB-PROG PIC X(75)
       VALUE 'C:\Users\google\Program3Call'.

   PROCEDURE DIVISION.
   PERFORM 200-INITIALIZATION-RTN.
  *Read and process all student records
   PERFORM 200-PROCESS-STUDENT-RECORD-RTN
       UNTIL STUFILE-EOF-FLAG = "YES".
   PERFORM 200-FINISH-RTN.
   STOP RUN.

   200-INITIALIZATION-RTN.
       PERFORM 300-OPEN-FILES-RTN.
  *****Load all program records into the table
       PERFORM 300-LOAD-PROGRAM-TABLE-RTN
           VARYING PROG-SUB FROM 1 BY 1
           UNTIL PROG-SUB > 20 OR PROG-EOF-FLAG = "YES".
       PERFORM 300-INITIALIZE-REPORT-FILE-RTN.
       PERFORM 300-INITIALIZE-COUNTERS-RTN.

   200-PROCESS-STUDENT-RECORD-RTN.
       PERFORM 300-READ-STUDENT-RECORD-RTN.
       IF STUFILE-EOF-FLAG NOT EQUALS "YES"
  *********Get the program name
           PERFORM 300-GET-PROGRAM-NAME-RTN
               VARYING PROG-SUB FROM 1 BY 1 UNTIL
               FOUND-PROG-FLAG = "YES" OR PROG-SUB > 20
           PERFORM 300-GET-STUDENT-AVERAGE
           PERFORM 300-PRINT-STUDENT-REPORT-RTN
       END-IF.

   200-FINISH-RTN.
       PERFORM 300-PRINT-COUNTERS-RTN.
       PERFORM 300-CLOSE-FILES-RTN.

   300-OPEN-FILES-RTN.
       OPEN INPUT STUDENT-FILE-IN.
       OPEN INPUT PROGRAM-FILE-IN.
       OPEN OUTPUT STUDENT-REPORT-FILE-OUT.

   300-LOAD-PROGRAM-TABLE-RTN.
       READ PROGRAM-FILE-IN
       AT END MOVE "YES" TO PROG-EOF-FLAG
       NOT AT END MOVE PROGRAM-CODE-IN TO PROGRAM-CODE (PROG-SUB)
                  MOVE PROGRAM-NAME-IN TO PROGRAM-NAME (PROG-SUB).

   300-INITIALIZE-REPORT-FILE-RTN.
       MOVE COLUMN-HEADER TO STUDENT-REPORT-RECORD-OUT.
       WRITE STUDENT-REPORT-RECORD-OUT.
       MOVE HEADER-LINE TO STUDENT-REPORT-RECORD-OUT.
       WRITE STUDENT-REPORT-RECORD-OUT.

   300-INITIALIZE-COUNTERS-RTN.
       MOVE 0 TO STUDENT-RECORDS-READ-CTR.
       MOVE 0 TO STUDENT-REPORTS-WRITTEN-CTR.

   300-READ-STUDENT-RECORD-RTN.
       READ STUDENT-FILE-IN
           AT END MOVE "YES" TO STUFILE-EOF-FLAG
           NOT AT END ADD 1 TO STUDENT-RECORDS-READ-CTR.

   300-GET-PROGRAM-NAME-RTN.
       IF PROGRAM-CODE (PROG-SUB) = PROGRAM-OF-STUDY
           MOVE PROGRAM-NAME (PROG-SUB) TO PROGRAM-NAME-OUT
           MOVE "YES" TO FOUND-PROG-FLAG
       END-IF.

   300-GET-STUDENT-AVERAGE.
        CALL WW-SUB-PROG USING WW-SEND-AREA.

   300-PRINT-STUDENT-REPORT-RTN.
       MOVE "NO" TO FOUND-PROG-FLAG.
       MOVE STUDENT-NAME-IN TO STUDENT-NAME.
       MOVE TUITION-OWED-IN TO TUITION-OWED.
       MOVE STUDENT-REPORT-RECORD TO STUDENT-REPORT-RECORD-OUT.
       WRITE STUDENT-REPORT-RECORD-OUT.
       ADD 1 TO STUDENT-REPORTS-WRITTEN-CTR.

   300-PRINT-COUNTERS-RTN.
       DISPLAY "Student records read: ", STUDENT-RECORDS-READ-CTR.
       DISPLAY "Student reports written: ",
           STUDENT-REPORTS-WRITTEN-CTR.

   300-CLOSE-FILES-RTN.
       CLOSE STUDENT-FILE-IN, PROGRAM-FILE-IN
           STUDENT-REPORT-FILE-OUT.


   END PROGRAM Project2.

这是我的调用程序:

  ******************************************************************
  * Author: Desiree Hanuman
  * Date: August 14th 2021
  * Purpose:Call Section code for project 3
  * Tectonics: cobc
  ******************************************************************
   IDENTIFICATION DIVISION.
   PROGRAM-ID. Program3Call.
   DATA DIVISION.
   LINKAGE SECTION.
   01 LS-STUDENT-AVERAGE-AREA.
       05 COURSE-AVERAGE-1 PIC 9(3).
       05 COURSE-AVERAGE-2 PIC 9(3).
       05 COURSE-AVERAGE-3 PIC 9(3).
       05 COURSE-AVERAGE-4 PIC 9(3).
       05 COURSE-AVERAGE-5 PIC 9(3).
       05 STUDENT-AVERAGE  PIC 9(3).

   PROCEDURE DIVISION.
   MAIN-PROCEDURE.
       100-STUDENT-AVERAGE.
             PERFORM 300-CALCULATE-AVERAGE-RTN.


       300-CALCULATE-AVERAGE-RTN.
       COMPUTE STUDENT-AVERAGE ROUNDED = (COURSE-AVERAGE-1 +
           COURSE-AVERAGE-2 + COURSE-AVERAGE-3 + COURSE-AVERAGE-4 +
           COURSE-AVERAGE-5) / 5.
   GOBACK.

我不是 OpenCobol 的用户,但是,根据他们在第 7 节中的手册,有很多方法可以完成您想要的。

但最简单的是在一个命令行中静态编译和link主程序和子程序:

cobc -x Project2.cbl Program3Call.cbl

在大多数 COBOL 实现中 CALL 的正常方法是仅指定模块名称 - 没有路径或扩展名。
然后你要么做“静态链接”(如斯科特下面对 OpenCOBOL/GnuCOBOL 的回答,只需在命令行上指定所有源并使用 -x [fat 可执行文件] 或 -b [fat 模块,然后可以用 cobcrun] 调用,通常用 -static);或者做“动态链接”(所有模块的单独编译)并在配置文件中或通过环境变量指定模块路径。对于 OpenCOBOL/GnuCOBOL,这是 COB_LIBRARY_PATH

这个例子适合我。

请记住,dll文件例程模块的名称必须与例程名称相同。

无需重新配置 OpenCobol 路径库。

我使用 OpenCobol 4.7.6。

代码:

  1. 主程序(文件构建“MAINPROG.exe”)

    IDENTIFICATION DIVISION.
    PROGRAM-ID. "MAINPROG".
    ENVIRONMENT DIVISION.
    
    DATA DIVISION.
    
    WORKING-STORAGE SECTION.
    
    01  X PIC X(1).
    
    01  INPUTS.
        05 PRM-LENGTH PIC  S9(4) COMP.
        05 INPUT1     PIC   9(2).
        05 INPUT2     PIC   9(2).
    
    PROCEDURE DIVISION.
    
    MAIN-PARA.
        MOVE 12 TO INPUT1.
        MOVE 13 TO INPUT2.
        CALL 'MFPROG1' USING  PRM-LENGTH, INPUT1, INPUT2.
        ACCEPT X.
        STOP RUN.
    
    END PROGRAM "MAINPROG".
    
  2. Rutine 程序(文件构建模块“MFPROG1.dll”)

    IDENTIFICATION DIVISION.
    PROGRAM-ID. "MFPROG1".
    ENVIRONMENT DIVISION.
    DATA DIVISION.
    
    WORKING-STORAGE SECTION.
    
    01 OUTPUT-DATA    PIC  9(4).
    
    LINKAGE SECTION.
    
    01 PARM-BUFFER.
       05 PARM-LENGTH    PIC S9(4) COMP.
       05 PARM-INPUT1    PIC  9(2).
       05 PARM-INPUT2    PIC  9(2).
    
    PROCEDURE DIVISION USING PARM-BUFFER.
    
    MAIN-PARA.
        COMPUTE OUTPUT-DATA = PARM-INPUT1 + PARM-INPUT2.
        DISPLAY 'PARM-INPUT1: ' PARM-INPUT1.
        DISPLAY 'PARM-INPUT2: ' PARM-INPUT2.
        DISPLAY 'SUM VALUE  : ' OUTPUT-DATA.
        GOBACK.
    
    END PROGRAM "MFPROG1".