Sorry, two errors:
the INIT (15) on the V1 definition is again there, should be omitted,
and END TESTPGM should begin in column 2.
Kind regards
Bernd
Am 24.03.2014 08:44, schrieb Bernd Oppolzer:
> I now managed to test the code on a real z/OS system;
> there were two remaining errors left:
>
> a) the const on the parameter list of the C function had to be replaced;
> if not, there are compiler warnings, because p1 is changed in the
> function
>
> b) when putting the null byte into buffer, the index must be 20, not 21
> (C array indices counting from zero; a compiler warning made this
> obvious).
>
> After that, the program ran successfully and gave the expected output.
>
> Kind regards
>
> Bernd
>
>
> Corrected source:
>
>
> TESTPGM: PROC OPTIONS (MAIN);
>
> DCL TESTPLI EXTERNAL ENTRY
> (PTR, /* ADDR (CHAR) */
> BIN FIXED (31),
> PTR); /* ADDR (PCRE) */
>
> DCL PARMC CHAR (20) INIT ('ENTRY VALUE');
> DCL PARMI BIN FIXED (31) INIT (15);
> DCL 1 STRUCT,
> 3 V1 BIN FIXED (31), INIT (15);
> 3 V2 BIN FIXED (31);
>
> PUT SKIP LIST (PARMC);
> PUT SKIP LIST (PARMI);
>
> CALL TESTPLI (ADDR (PARMC),
> PARMI,
> ADDR (STRUCT));
>
> PUT SKIP LIST (PARMC);
> PUT SKIP LIST (PARMI);
>
> END TESTPGM;
>
>
> /**************************************/
> /* Test C interface to PL1 */
> /**************************************/
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
>
> int testpli (char **p1,
> int *p2,
> void **p6)
>
> {
> char buffer [21];
> int intfield;
>
> memcpy (buffer, *p1, 20);
> buffer [20] = 0x00;
> printf ("%s\n", buffer);
> memset (*p1, ' ', 20);
> memcpy (*p1, "RETURN VALUE", 12);
>
> intfield = *p2;
> printf ("%d\n", intfield);
> *p2 = 13;
>
> return 27;
> }
>
>
>
>
>
>
>
> Am 23.03.2014 11:33, schrieb Bernd Oppolzer:
>> There is an error in the definition of STRUCT,
>> the INIT (15) after V1 should be omitted, the correct definition is
>>
>> DCL 1 STRUCT,
>> 3 V1 BIN FIXED (31),
>> 3 V2 BIN FIXED (31);
>>
>> Sorry
>>
>> Bernd
>>
>>
>>
>> Am 23.03.2014 11:31, schrieb Bernd Oppolzer:
>>> Hi Z.,
>>>
>>> I'd like to start with the following source:
>>>
>>>
>>> DCL TESTPLI EXTERNAL ENTRY
>>> (PTR, /* ADDR (CHAR) */
>>> BIN FIXED (31),
>>> PTR); /* ADDR (PCRE) */
>>>
>>> DCL PARMC CHAR (20) INIT ('ENTRY VALUE');
>>> DCL PARMI BIN FIXED (31) INIT (15);
>>> DCL 1 STRUCT,
>>> 3 V1 BIN FIXED (31), INIT (15);
>>> 3 V2 BIN FIXED (31);
>>>
>>> PUT SKIP LIST (PARMC);
>>> PUT SKIP LIST (PARMI);
>>>
>>> CALL TESTPLI (ADDR (PARMC),
>>> PARMI,
>>> ADDR (STRUCT));
>>>
>>> PUT SKIP LIST (PARMC);
>>> PUT SKIP LIST (PARMI);
>>>
>>>
>>>
>>>
>>> /**************************************/
>>> /* Test C interface to PL1 */
>>> /**************************************/
>>>
>>> int testpli (const char **p1,
>>> int *p2,
>>> void **p6)
>>>
>>> {
>>> char buffer [21];
>>> int intfield;
>>>
>>> memcpy (buffer, *p1, 20);
>>> buffer [21] = 0x00;
>>> printf ("%s\n", buffer);
>>> memset (*p1, ' ', 20);
>>> memcpy (*p1, "RETURN VALUE", 12);
>>>
>>> intfield = *p2;
>>> printf ("%d\n", intfield);
>>> *p2 = 13;
>>>
>>> return 27;
>>> }
>>>
>>>
>>> you would have to put the PL/1 excerpts on the top
>>> into your PL/1 caller and the C test function maybe needs
>>> some ANSI #includes to make it complete.
>>>
>>> Regarding your request, there are some limitations;
>>>
>>> because you use an old compiler, you will not be able
>>> to pass integers by value and char * without descriptors
>>> (only by using nasty workaround). That's why I limited the
>>> example above to int * and char **. I showed in the C function
>>> how to deal with those parameter types. The parameter passed
>>> is printed in the C function, then changed, and then printed again
>>> on the PL/1 side.
>>>
>>> Another topic here is, that the PL/1 char in this case is not
>>> null-terminated, but the C function like prints expects a
>>> null termination, so the C function adds a zero byte.
>>> That might not be necessary in your PCRE case, or:
>>> it could be the other way round, that is: the PL/1 side has
>>> to take care to add the zero byte.
>>>
>>> I would encourage you to test these code snippets, and once
>>> you are convinced that they work, then we go ahead and
>>> work again on your PCRE project. The problems that you sent
>>> me offline IMHO have nothing to do with the parameter passing
>>> mechanism.
>>>
>>> Kind regards
>>>
>>> Bernd
>>>
>>>
>>>
>>>
>>> Am 23.03.2014 08:07, schrieb Z.A.:
>>>> Hi All
>>>> Does any of you have a working example in which the PL/1 calls a C
>>>> function with any of these parameters
>>>>
>>>> char * varname
>>>> char ** varname
>>>> int varname
>>>> int * varname
>>>> sometype * varname
>>>>
>>>> and this routine returns any of
>>>> int
>>>> char *
>>>> sometype *
>>>>
>>>> Especially, I am interested in cases where the C is NOT aware of
>>>> any descriptor while the PL/1 is compiled in most common way. I am
>>>> not interested in the theory, I tried to work with the theory to no
>>>> avail. I really need to see a working example (relevant snippets)
>>>> ideally, i would like to see both sides behavior (i.e. how the PL/1
>>>> calling using any specific signature and how the C is handling that
>>>> parm.
>>>>
>>>> Any response would be highly appreciated.
>>>>
>>>> Thanks
>>>>
>>>> ZA
>>>>
>>>
>>>
>>
>>
>
|