On Tue, May 30, 2017 at 1:26 PM, scott Ford <idfli...@gmail.com> wrote:

> John,
>
> I didnt realize you could call C library functions directly, very cool  ,
> here is what i would like to do:
>
>      FILE SECTION.
>        WORKING-STORAGE SECTION.
>        77 TESTSTR   PIC X(30) VALUE SPACES.
>        77 VAR1      PIC S9(9) BINARY VALUE 5.
>        PROCEDURE DIVISION.
>        0000-MAIN.
>       *     MOVE 1 TO P1.
>       *     DISPLAY 'P1: ' P1
>       *     CALL 'CFUNC' USING P1 RETURNING P2
>       *     DISPLAY 'P1: ' P1
>       *     DISPLAY 'P2: ' P2
>             STRING 'TEST STRING' ,
>                LOW-VALUE
>                 DELIMITED BY SIZE INTO TESTSTR
>             DISPLAY 'CALL CENTRY USING: ' TESTSTR
>             CALL 'CENTRY' USING  TESTSTR.
>             GOBACK.
>
> <c>
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> void CENTRY(char* mystring)
> {
>   printf("my string: %s \n",mystring);
> }
>
> I am trying to understand how to perform the call and pass a string and or
> a integer ...
>
> Thanks John..
>
> Regards.
> Scott
>
>
>
​You example above should work fine. The standard COBOL parameter list
​USING TESTSTR passes a single parameter which is the pointer to TESTSTR
which, in C speak, is char *.  In general, for me, I think of "what code
does the sending language's compiler generate?" and "what does the
receiving language expect?". Inter-operating with C is set up in the
current COBOL compilers. At least back to 4.2. The reference is:

https://www.ibm.com/support/knowledgecenter/en/SS6SG3_4.2.0/com.ibm.entcobol.doc_4.2/PGandLR/ref/rlpscall.htm

What you need to remember is that C is a "call by value" language. That is,
the C languages expects the _value_ (not a pointer to a value) to be in the
calling list pointed to by GPR1. So when you see a definition like: <data
type> *data_name; the C program is expecting a _pointer_. But if you see
something like: <data type> data_name, the C program is expecting the
actual value (however long) to be at the relative position in the calling
sequence. This is _not_ standard OS linkage! If you look at the above, you
will see that the CALL verb has three clauses you can use. The historic one
is "BY REFERENCE", which means "pass a pointer to the actual data are in
storage". This allows the CALL'ed routine to update the area and have that
changed value available to the caller. The one for C will often be "BY
VALUE". This tells the COBOL compiler to copy the current _value_ of the
variable named directly into the calling parameter. This is compatible with
the standard way of passing integers ( e.g. CALL 'CENTRY2' USING BY VALUE
INT-VALUE. 77 INT-VALUE PIC S9(9) COMP. and the prototype: void centry2(int
some-value);). The last is "BY CONTENT" and I don't know why it exists.
Basically, the COBOL compiler reserves an area in dynamic storage, copies
the contents of the named variable into that area, then passes the address
of the dynamic area to the subroutine. This basically makes the original
content in the caller unalterable.

really cut down examples:

77 INT-VALUE PIC S9(9) COMP. *> C language int32_t
77 INT-VALU2 PIC S9(9) COMP.
77 CHAR-VALUE PIC X(40). *> C language char x[40];

CALL 'CENTRY' USING BY REFERENCE CHAR-VALUE,
                    BY VALUE INT-VALUE,
                    BY REFERENCE INT2-VALUE
END-CALL

== C prototype for above:

void centry (char *char_value, int int_value, int *int2_value);
//
// note you can change char_value which will affect calling variable
// note you can change int_value which DOES NOT affect calling variable
// note you can change int2_value which DOES affect calling variable

​Note that you could do something like:

CALL 'CENTRY' USING BY VALUE CHAR-VALUE​, INT-VALUE, BY REFERENCE
INT2_VALUE.

with

void centry (char char_value[40], int int_value, int *int2_value);

​But it most likely _won't_ be what you want!!! What the COBOL compiler
will do is create a calling list area. Copy the 40 bytes from CHAR-VALUE
directly into the calling parameter list. Follow that by the 4 bytes value
in INT-VALUE. Followed by a 4 byte address of INT2-VALUE. That is, the GPR1
will point to 48 bytes of data. In addition, changing char_value does NOT
change the value back in the COBOL program. So, in ever case that I've ever
see, I've seen C "string" values (actually array of chars) passed by
​address not value.
​​
​I hope this was of some value. And that I didn't mess up.​



-- 
Windows. A funny name for a operating system that doesn't let you see
anything.

Maranatha! <><
John McKown

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN

Reply via email to