gnucobol-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [open-cobol-list] user generated final bindings, more day dreaming


From: Michael Anderson
Subject: Re: [open-cobol-list] user generated final bindings, more day dreaming
Date: Sun, 30 Jun 2013 14:34:52 -0500
User-agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/20130623 Thunderbird/17.0.7

On 06/30/2013 09:22 AM, Patrick wrote:
Hi Everyone

I find writing bindings difficult. I have never been able to write anything reusable by others, only for myself.

structs are tough to work with from outside of C, at least for me and other types can be annoying like enumerations, in that you have to figure out the int they represent.

It's not that hard, I think you're making it harder than it really is.
Follow me here, a not so quick example to show that asking Cobol to pass data to C, is not so difficult.

      Move 0   To wsEvents-status.
      Move 2.0 To wsEvents-seconds.
      Perform Wait-for-Events.

So, in the paragraph “Wait-for-Events”:

      Call "wsEvents" Using wsEvents-seconds Giving wsEvents-status.
      Move wsEvents-status To WebSocket-Wait-Status.
      Evaluate True *> for logging only
        When WebSocket-Timeout
             Move "WebSocket TIMEOUT" to logmsg
             Perform write-logmsg
        When Browser-Sent-Data
             Move "WebSocket Ready To Read" to logmsg
             Perform write-logmsg
        When other
             Move "WebSocket State is unknown" to logmsg
             Perform write-logmsg
      End-Evaluate.

To explain “wsEvents”, it is one of many C functions that I wrote, and linked into my OpenCobol program, and it gives my Cobol application a time-out on stdin. There maybe an easier way to have a time-out on an accept from stdin, but that's not my point here. The point is “bindings”, specifically, binding of variables, and linking the correct Cobol datatype to the correct C datatype.

wsEvents It looks like so:

/**************** wsEvents *******************/
int wsEvents (ev_tstamp *seconds) {
    LogDebug("wsEvents: begins with a %5.3f second timeOut", *seconds);
   struct ev_loop *loop = ev_default_loop (0);

   ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ);
   ev_io_start (loop, &stdin_watcher);

   ev_timer_init (&timeout_watcher, timeout_cb, *seconds, 0.);
   ev_timer_start (loop, &timeout_watcher);

   ev_loop (loop, 0);   

   ev_io_stop (EV_A_ &stdin_watcher);
   ev_timer_stop (EV_A_ &timeout_watcher);
    LogDebug("wsEvents: Ends EVENT_STATUS = %d", EVENT_STATUS);

   return EVENT_STATUS;
 }

In C we can just invent our own datatype using typedef!
So, from within Cobol, What the heck is the C datatype "ev_tstamp"?

I can guess that it is a number of seconds, I would think it could be of type int.
The only way to be sure is to find the 'ev_tstamp' typedef in ev.h header file, where is was invented/defined.

What do I find:
typedef double ev_tstamp;

It turns out to be a double, which I know is a 8 byte float, so what is that in Cobol?

 1 wsEvents-seconds      Usage is COMPUTATIONAL-2.

Similarly: ev_tstamp could have turned out to be a struct of some kind or whatever, but it was just a double.....
another example using a struct.

A rather large struct in C, something else I used to create a library "vuelib" in C, callable by Cobol:

struct vcom {
     short  cstatus;
     short  language;
     short  comarealen;
     short  userbuflen;
     short  cmode;
     short  lastkey;
     short  numerrs;
     short  windowenh;
     short  multiusage;
     short  labeloption;
     UCHAR   cfname[16];
     UCHAR   nfname[16];
     short  repeatapp;
     short  freezapp;
     short  cfnumlines;
     short  dbuflen;
     short  filler0;
     short  lookahead;
     short  deleteflag;
     short  showcontrol;
     short  filler1;
     short  printfilnum;
     short  filerrnum;
     short  errfilenum;
     short  formstoresize;
     short  filler2;
     short  filler3;
     short  filler4;
     int    numrecs;
     int    recnum;
     short  filler5;
     short  filler6;
     short  filen;
     short  filler7;
     short  filler8;
     short  filler9;
     short  filler10;
     short  filler11;
     short  retries;
     short  termoptions;
     short  environ;
     short  usertime;
     short  identifier;
     short  labinfo;
     };

// Now define a new datatype called vcom_t

typedef struct vcom vcom_t;


The same struct defined in Cobol would be:

  01 COMAREA.
     03  CSTATUS       PIC S9(4) COMP.
         88  GOOD-CALL        VALUE 0.
         88  TIME-OUT         VALUE 160.
         88 NO-VIEW-ERROR     VALUE 0.
     03  LANGUAGE      PIC S9(4) COMP.
     03  COMAREALEN    PIC S9(4) COMP.
     03  USERBUFLEN    PIC S9(4) COMP.
     03  CMODE         PIC S9(4) COMP.
     03  LASTKEY       PIC S9(4) COMP.
     03  NUMERRS       PIC S9(4) COMP.
     03  WINDOWENH     PIC XX.
     03  FILLER REDEFINES WINDOWENH.
         10  FILLER           PIC X.
         10  V-ENHANCE        PIC X.
     03  MULTIUSAGE    PIC S9(4) COMP.
     03  LABELOPTIONS  PIC S9(4) COMP.
     03  CFNAME        PIC X(16).
     03  NFNAME        PIC X(16).
     03  REPEATAPP     PIC S9(4) COMP.
     03  FREEZEAPP     PIC S9(4) COMP.
     03  CFNUMLINES    PIC S9(4) COMP.
     03  DBUFLEN       PIC S9(4) COMP.
     03  FILLER        PIC S9(4) COMP.
     03  LOOKAHEAD     PIC S9(4) COMP.
     03  DELETEFLAG    PIC S9(4) COMP.
     03  SHOWCONTROL   PIC S9(4) COMP.
     03  FILLER        PIC S9(4) COMP.
     03  PRINTFILNUM   PIC S9(4) COMP.
     03  FILERRNUM     PIC S9(4) COMP.
         88 NO-FILE-ERROR     VALUE 0.
     03  ERRFILENUM    PIC S9(4) COMP.
     03  FORMSTORESIZE PIC S9(4) COMP.
     03  FILLER        PIC S9(4) COMP OCCURS 3.
     03  NUMRECS       PIC S9(6) COMP.
     03  RECNUM        PIC S9(6) COMP.
     03  FILLER        PIC S9(4) COMP OCCURS 2.
     03  FILEN         PIC S9(4) COMP.
     03  FILLER        PIC S9(4) COMP OCCURS 5.
     03  RETRIES       PIC S9(4) COMP.
     03  TERMOPTIONS   PIC S9(4) COMP.
     03  AUTOREAD-OPTION REDEFINES
         TERMOPTIONS        PIC S9(4) COMP .
     03  ENVIRON       PIC S9(4) COMP.
     03  USERTIME      PIC S9(4) COMP.
     03  IDENTIFIER    PIC S9(4) COMP.
     03  LABINFO       PIC S9(4) COMP.

Passing vcom_t data from Cobol to C:

     MOVE LOW-VALUES          TO COMAREA.
     MOVE ZERO                TO LANGUAGE.
     MOVE 60                  TO COMAREALEN.
     MOVE 1                   TO LABELOPTIONS.
     MOVE ZERO                TO LOOKAHEAD.
     MOVE 4                   TO FORMSTORESIZE.
     MOVE SPACES TO FILENAME.
     string "QCSFORM.QC.SOURCE" delimited by size inTO FILENAME.
     move "testform" to NFNAME.
     CALL "VOPENFORMF" USING COMAREA FILENAME.
     IF CSTATUS OF COMAREA NOT = 0
      MOVE "Y" TO STOP-NOW
      Call "VSHOWERRMSG" Using COMAREA.

What does this look like from the C side:

NOTE: that
CALL "VOPENFORMF" USING COMAREA FILENAME.

will (by default) only pass the memory addresses of COMAREA and FILENAME.
Same as:
CALL "VOPENFORMF" USING
            By Reference COMAREA
            By Reference FILENAME.


So, in the C code we use * to say this a memory address pointer.

void  VOPENFORMF(vcom_t *comarea, UCHAR *VopenFile);

Then from the C side you can reference these items like  so:
     fprintf (stdout, "DEBUG: VOPENFORMF language       : %d \n", comarea->language);
     fprintf (stdout, "DEBUG: VOPENFORMF comarealen     : %d \n", comarea->comarealen);
     fprintf (stdout, "DEBUG: VOPENFORMF labeloptions   : %d \n", comarea->labeloption);
     fprintf (stdout, "DEBUG: VOPENFORMF lookahead      : %d \n", comarea->lookahead);
     fprintf (stdout, "DEBUG: VOPENFORMF formstoresize  : %d \n", comarea->formstoresize);
     fprintf (stdout, "DEBUG: VOPENFORMF nfname         : %s \n", comarea->nfname);
   

So, not much marshalling to do here, just passing addresses and such.....

I've done similar stuff with AcuCobol, fujitsu, and others, works with minimal confusion.
However, what makes OpenCobol so good with this, is that they (OC and Cobol) are using the same compiler, which is just too cool!

The philosophy here is "Application Programming vs Systems Programming".
Where Cobol is a application programming language, there are things that I do not want coded in my application, like wsEvents.
I could make all the calls to (ev_io_init, ev_io_start) directly from OpenCobol, but it is better not to clutter up my application with such things.

You can't find a better language for business applications than Cobol,
likewise, you can't find a better Systems programming language than C (not to be confused with C++ or C#).

I can't begin to THANK all the OC developers enough for giving us one compiler for both languages,
OC is the best! Thank You OC developers!

--
Mike.

PS: think of enumerations as Cobol 88 level bools. And COBOL Function Length combined with C sizeof will also help you understand various data types.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]