Oppolzer - Informatik / Blog


Blog-Hauptseite      Neuester Artikel      Älterer Artikel      Neuerer Artikel      Älterer gleiche Kategorie      Neuerer gleiche Kategorie

PL1-L - Diskussion über PL/1-Interface für PCRE (Perl compatible Reg. Ex)

Subject:

Re: calling C from PL/I....

From:

Bernd Oppolzer <bernd.oppolzer@T-ONLINE.DE>

Reply-To:

PL1 (language) discussions <PL1-L@LISTSERV.DARTMOUTH.EDU>

Date:

2014.02.24 10:16:42


Further "book reading" (programming guide) shows:

dcl fopen ext("fopen")
entry( char(*) varyingz byaddr,
char(*) varyingz byaddr )
returns( byvalue type file_handle )
options ( nodescriptor );

there are indeed PL/1 language features to deal with C function results,
including pointers;

see the example above; the returns clause specifies that the fopen function
(well known to C coders) returns a pointer of type file_handle.

So you may take this as an example and define your function COMPILE8
in the same way.

Kind regards

Bernd



Am 24.02.2014 10:00, schrieb Bernd Oppolzer:
> I did some "book reading" (language reference for the EP PL/1 compiler V4.4).
>
> If you define your external entry with option ASSEMBLER or COBOL
> (C doesn't exist), you will get the effect that
>
> "the PLIRETV() value is taken as the RETURN value of the procedure"
>
> in both cases.
>
> PLIRETV () is BIN FIXED (31), not BIN FIXED (15) in the meantime,
>
> so you could in fact define the C function as ASSEMBLER function (in PL/1),
> giving a BIN FIXED (31) result, and then convert the BIN FIXED (31) result
> to a pointer (which it really is).
>
> This is not very nice, but it should work, IMHO.
>
> No need for a wrapper function, in this case.
>
> Kind regards
>
> Bernd
>
>
>
> Am 24.02.2014 09:30, schrieb Bernd Oppolzer:
>> I would like to add:
>>
>> the RETURN facility in PL/1 is somehow different from C and maybe
>> other languages.
>>
>> In C, the return values are limited to values that fit into a register, AFAIK.
>> So the pointer, that is returned in your case, is technically returned (at the mainframe)
>> in the same way as the return code, that is, Register 15.
>>
>> In PL/1, if you use RETURN, it is implemented as an additional parameter,
>> following the other parameters. If you RETURN a value in PL/1, you can
>> still use PLIRETC / PLIRETV, because these are different techniques.
>>
>> X = FUNC (A,B C);
>>
>> in the PL/1 mainframe implementation is the same as
>>
>> CALL FUNC (A,B,C,X)
>>
>> leaving room for using PLIRETC / PLIRETV in both cases.
>>
>> This is not compatible with C function results.
>>
>> Your COBOL coding, which obviously works, shows that things must be
>> different in COBOL.
>>
>> (maybe there are options in PL/1 to change this behaviour, but I
>> didn't want to use them so far)
>>
>> Kind regards
>>
>> Bernd
>>
>>
>>
>>
>> Am 24.02.2014 09:17, schrieb Bernd Oppolzer:
>>> First:
>>>
>>> You don't have to "change" your open source library, you only code
>>> a small wrapper function on top of it to make it easier to call it from PL/1.
>>>
>>> Then:
>>>
>>> There are two issues with this function. The first one are the call by value
>>> parms, which can be easily resolved using the BYVALUE keyword of
>>> newer PL/1 compilers. The second one is the handling of the C function
>>> result.
>>>
>>> Historically, the function results of C correspond with the PLIRETV ()
>>> return codes of PL/1, and they are limited to BIN FIXED (15) values.
>>> So we have an issue here. I don't know if we have newer compiler
>>> features to cope with that. I simply don't care, because at our site
>>> we always build wrapper functions to build a PL/1 friendly interface
>>> to such functions. This is no big deal and can be done within hours.
>>> We did this since the early 1990s.
>>>
>>> This way, I don't even have inform the PL/1 compiler that the external
>>> function is written in C. The C wrapper function presents a PL/1 compatible
>>> interface to PL/1, and everything is fine.
>>>
>>> We did this in the past even to get rid of the by value parms. All our PL/1 friendly
>>> interfaces only had (from a C perspective) int function results (that is, return codes,
>>> suitable for PLIRETV ()), and pointers as parameters, suitable for BYADDR parms.
>>>
>>> If we could not convince our external partners providing C functions to
>>> provide such interfaces to their software, we built wrapper functions ...
>>>
>>> For example: I have a powerful XML parser (and generator) written in ANSI C,
>>> and to make it callable from PL/1, I have a wrapper function around it that allows
>>> us to call its different functions (xmlp_open, xml_parser, xmlp_close, ...) using
>>> one function callable from PL/1 - with different function codes.
>>>
>>> If you want to know more about the details, contact me offline.
>>>
>>> Kind regards
>>>
>>> Bernd
>>>
>>>
>>>
>>>
>>> Am 24.02.2014 03:36, schrieb Z.A.:
>>>>  Bernd Oppolzer wrote:
>>>>
>>>>
>>>> >of course, if you want for example all parameters to be
>>>> >passed by value - just to have the same look and feel for
>>>> >all of them - this is perfectly simple.
>>>>
>>>> >To have all of them passed by reference, you can do this, too,
>>>> >if the wrapper function takes care of that.
>>>>
>>>> The PCRE is an open source library (compile8 is only one of the API calls)
>>>> and we are bound by its definitions and call conventions.
>>>> Calls from COBOL do not have any issue and the call below works:
>>>>
>>>>            call 'COMPILE8' using by value     pcrews-pattern-ptr
>>>>                 BY VALUE 0
>>>>                 BY reference pcrews-error-ptr
>>>>                 BY reference pcrews-erroffset
>>>>                 BY VALUE pcrews-null-ptr
>>>>                 RETURNING RE
>>>>            end-call
>>>>
>>>> where all -ptr are defined as USAGE POINTER and RE is defined as:
>>>> 01 RE                        USAGE POINTER VALUE NULL.
>>>>
>>>>
>>>
>>>
>>

Blog-Hauptseite      Neuester Artikel      Älterer Artikel      Neuerer Artikel      Älterer gleiche Kategorie      Neuerer gleiche Kategorie