Using GnuCOBOL (cobc) 3.2.0 on Windows, I'm trying to write a simple COBOL program that calls a subroutine in another file, but the subroutine is not found.
foo1.cob
:
IDENTIFICATION DIVISION.
PROGRAM-ID. MAINPROG.
PROCEDURE DIVISION.
MAIN-PROCEDURE.
PERFORM "SUB-SAY-HELLO1".
CALL "SUB-SAY-HELLO2".
STOP RUN.
SUB-SAY-HELLO1.
DISPLAY "HELLO1".
foo2.cob
:
IDENTIFICATION DIVISION.
PROGRAM-ID. SUBPROG.
PROCEDURE DIVISION.
SUB-SAY-HELLO2.
DISPLAY "HELLO2!".
EXIT PROGRAM.
First I run the command
cobc -m foo2.cob
that produces foo2.dll
.
Then I run the command
cobc -x foo1.cob -L c:\dev -l foo2
that produces foo1.exe
.
Then I try to execute foo1.exe, and get the following output:
HELLO1
libcob: error: module 'SUB-SAY-HELLO2' not found
What do I need to do for my main program to find the sub program?
Using GnuCOBOL (cobc) 3.2.0 on Windows, I'm trying to write a simple COBOL program that calls a subroutine in another file, but the subroutine is not found.
foo1.cob
:
IDENTIFICATION DIVISION.
PROGRAM-ID. MAINPROG.
PROCEDURE DIVISION.
MAIN-PROCEDURE.
PERFORM "SUB-SAY-HELLO1".
CALL "SUB-SAY-HELLO2".
STOP RUN.
SUB-SAY-HELLO1.
DISPLAY "HELLO1".
foo2.cob
:
IDENTIFICATION DIVISION.
PROGRAM-ID. SUBPROG.
PROCEDURE DIVISION.
SUB-SAY-HELLO2.
DISPLAY "HELLO2!".
EXIT PROGRAM.
First I run the command
cobc -m foo2.cob
that produces foo2.dll
.
Then I run the command
cobc -x foo1.cob -L c:\dev -l foo2
that produces foo1.exe
.
Then I try to execute foo1.exe, and get the following output:
HELLO1
libcob: error: module 'SUB-SAY-HELLO2' not found
What do I need to do for my main program to find the sub program?
Share Improve this question asked Mar 11 at 10:18 HelenaHelena 1,0972 gold badges13 silver badges32 bronze badges 2- What does the manual say? And as I'm not 100'% sure - what do you want to achieve? Dynamic loading of programs (= something that resolves the module at run-time, which includes finding both the entry-point/program-id and the file it is located in) or static linking (where everything is in one binary already and not "searched" at runtime at all)? – Simon Sobisch Commented Mar 11 at 12:06
- I would say that dynamic loading is what I want to achieve. – Helena Commented Mar 25 at 11:37
1 Answer
Reset to default 2EDIT: I first claimed what I want to do as not possible, but that is not true. I have now found out how to do it, which is explained below.
After more testing, and having a colleague of mine test this on the VSI VMS Integrity operating system with the native VSI COBOL compiler, it appears that what I wanted to achieve is not possible in COBOL in the way that I did it. One COBOL program cannot specify multiple subroutines that are callable separately - a single program is instead callable, and will then execute the PROCEDURE DIVISION
from the top.
In my original posted code, the
CALL "SUB-SAY-HELLO2".
can be replaced with
CALL "SUBPROG".
Which will execute just fine with the following output
HELLO1
HELLO2!
The SUBPROG
program will be executed from the top of the PROCEDURE DIVISION
, stopping at EXIT PROGRAM
.
If multiple subroutines are to be declared, they need to be declared in separate programs. A COBOL file can however include multiple programs, so if the file foo2.cob
above was to be changed to:
IDENTIFICATION DIVISION.
PROGRAM-ID. SUB-SAY-HELLO2.
PROCEDURE DIVISION.
SUB-ROUTINE.
DISPLAY "HELLO2!".
EXIT PROGRAM.
IDENTIFICATION DIVISION.
PROGRAM-ID. SUB-SAY-HELLO3.
PROCEDURE DIVISION.
SUB-ROUTINE.
DISPLAY "HELLO3!".
EXIT PROGRAM.
The main program foo1.cob
would be able to call the programs separately like this:
IDENTIFICATION DIVISION.
PROGRAM-ID. MAINPROG.
PROCEDURE DIVISION.
MAIN-PROCEDURE.
PERFORM SUB-SAY-HELLO1.
CALL "SUB-SAY-HELLO2".
CALL "SUB-SAY-HELLO3".
STOP RUN.
SUB-SAY-HELLO1.
DISPLAY "HELLO1".
This is supported both by GnuCOBOL and VSI COBOL. There is an ENTRY
statement that can also be used, which is supported by GnuCOBOL and IBM COBOL, but not VSI COBOL, which would allow for the foo2.cob
program to look like this instead:
IDENTIFICATION DIVISION.
PROGRAM-ID. SUBPROG.
PROCEDURE DIVISION.
ENTRY "SUB-SAY-HELLO2".
DISPLAY "HELLO2!".
EXIT PROGRAM.
ENTRY "SUB-SAY-HELLO3".
DISPLAY "HELLO3!".
EXIT PROGRAM.
And the foo1.cob
program can now call the entries in the same manner as mentioned above. This is not the approach I will use however, as my COBOL programs need to work for both GnuCOBOL and VSI COBOL.
NOTE: If these instructions are followed in GnuCOBOL but there are still link errors because the programs/entries are not found, this might be due to preloading being required. Set the environment variable COB_PRE_LOAD
to your built library, in this case (Windows example):
set COB_PRE_LOAD=C:\dev\foo2.dll