calling a COBOL program from a C program, ERROR LNKG2019: unresolved external symbol _verkoop referenced in function _main

StackOverflow https://stackoverflow.com/questions/20824661

  •  22-09-2022
  •  | 
  •  

I'm calling a COBOL program from a C program, but I keep getting following error: ERROR LNKG2019: unresolved external symbol _verkoop referenced in function _main.

Here is my C program:

#include <stdio.h>
#include "libcob.h"
//#pragma linkage (verkoop, COBOL)

extern void verkoop(char *productid, char *aantal);

int main(int argc, char *argv[])
{
    char *productid = "000020";
    char *aantal = "000200";
    COB_RTD = cob_get_rtd();
    cob_init(rtd, 0, NULL);
    printf("Hello world");  
    verkoop(productid, aantal);
    return 0;
}

Here is my COBOL program:

*************************************************************
* VERKOOP  
*************************************************************
       IDENTIFICATION DIVISION.
       PROGRAM-ID. VERKOOP.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
       SELECT PRODUCTEN ASSIGN TO "BESTANDEN/PRODUCTEN"
           ACCESS MODE IS RANDOM
           ORGANIZATION IS INDEXED
           RECORD KEY IS PRODUCTID
           FILE STATUS IS WS-FILE-STATUS.

       DATA DIVISION.
       FILE SECTION.
       FD  PRODUCTEN BLOCK CONTAINS 10 RECORDS.
       01  PRODUCT.
           02 PRODUCTID PIC X(6).
           02 LEVERANCIERID PIC X(6).
           02 AANTAL PIC 9(6).
       WORKING-STORAGE SECTION.
       77  FOUT PIC X.
           88 PRODUCT-NIET-GEVONDEN VALUE 1.
       77 WS-PRODUCTID PIC X(6).
       77 WS-AANTAL PIC 9(6).
       77 WS-FILE-STATUS PIC XX.
       LINKAGE SECTION.
       01 LS-PRODUCTID PIC X(6).
       01 LS-AANTAL PIC 9(6).
       PROCEDURE DIVISION USING LS-PRODUCTID, LS-AANTAL.

       MAIN.
           PERFORM INITIALISEER
           PERFORM LEES-PRODUCT-IN
           PERFORM LEES-BESTAND
           PERFORM SLUIT-BESTAND
           STOP RUN.

       INITIALISEER.
           MOVE ZEROS TO PRODUCT
           OPEN I-O PRODUCTEN.
*          DISPLAY WS-FILE-STATUS..

       LEES-PRODUCT-IN.
           MOVE LS-PRODUCTID TO WS-PRODUCTID
           MOVE LS-AANTAL TO WS-AANTAL.
*          DISPLAY "GEEF PRODUCTID OP: "
*          ACCEPT WS-PRODUCTID
*          DISPLAY "GEEF AANTAL OP: "
*          ACCEPT WS-AANTAL.

       LEES-BESTAND.
*      DISPLAY "LEES-BESTAND"
       MOVE WS-PRODUCTID TO PRODUCTID
*      DISPLAY PRODUCTID
       READ PRODUCTEN INVALID KEY SET PRODUCT-NIET-GEVONDEN TO TRUE
       END-READ   
       DISPLAY "END-READ" WS-FILE-STATUS    
       IF PRODUCT-NIET-GEVONDEN PERFORM FOUTJE    
       ELSE 
       MOVE WS-PRODUCTID TO PRODUCTID
       SUBTRACT WS-AANTAL FROM AANTAL   
       PERFORM UPDATE-PRODUCT
       END-IF.


      UPDATE-PRODUCT.
        REWRITE PRODUCT INVALID KEY PERFORM FOUTJE.

        SLUIT-BESTAND.
*       DISPLAY "SLUIT-BESTAND"
           CLOSE PRODUCTEN.

        FOUTJE.
           DISPLAY "ER IS EEN FOUT OPGETREDEN"
*          DISPLAY WS-FILE-STATUS
           STOP RUN.

Both compiled using the cobc -c command in COBOL-IT COBOL Compiler Suite Enterprise for MS VC. I tried linking them with the following command : cobc -x -flink-only -o exercise productverkoop-c.obj verkoop.obj, that is when I get the error.

有帮助吗?

解决方案

As I suggested on a comment on your first question, it is easy to locate documentation for the compiler you are using (I found it before you confirmed which compiler, so it is genuinely easy).

http://www.cobol-it.com/images/datacorner/pdf/pdf_getstarted_compilersuite_01-2011.pdf

This contains, amongst others, an example of calling a COBOL program from a C program using exactly COB_RTD code you were given.

The case of the program file is important, as you will see in the example. I would make the PROGRAM-ID the same as the first part of the filename. This may be necessary for a static call (I've not read the document) and may be irrelevant for a dynamic call.

Also note the you are using STOP RUN in your COBOL program. GOBACK or EXIT PROGRAM is the normal way to return to the calling program, but if you are supposed to use STOP RUN you will find example code to deal with the results of the STOP RUN.

You will want to start from page 55 of the document, but the whole document is going to be of use to you if you continue to use COBOL-IT in your course.

Here are the simple example C and COBOL programs. The more complex example on Threading includes sample code to deal with the STOP RUN if you use it in the COBOL program.

Static linking of “C” programs with COBOL programs
The “C” program
/* hello.c */
#include <libcob.h>
extern int say(char *hello, char *world);
int main()
{
COB_RTD = cob_get_rtd();
int ret;
int return_status;
char hello[7] = "Hello ";
char world[7] = "World!";
cob_init(rtd, 0, NULL);
ret = say(hello, world);
cob_stop_run (rtd, return_status);
return ret;
}

The COBOL program

Say.cbl is passed two fields, which are described in the Linkage Section. Say.cbl DISPLAYs the two fields, and then exits.

say.cbl

IDENTIFICATION DIVISION.
PROGRAM-ID. say.
ENVIRONMENT DIVISION.
DATA DIVISION.
LINKAGE SECTION.
01 HELLO PIC X(6).
01 WORLD PIC X(6).
PROCEDURE DIVISION USING HELLO WORLD.
DISPLAY HELLO WORLD.
EXIT PROGRAM.

其他提示

I would first check to see if the symbol verkoop in the verkoop.obj is uppercase (use dumpbin), if it change all the references verkoop to VERKOOP e.g.:

#pragma linkage (VERKOOP, COBOL)

extern void VERKOOP(char *productid, char *aantal);

VERKOOP(productid, aantal);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top