IBM Mainframe Forum Index
 
Log In
 
IBM Mainframe Forum Index Mainframe: Search IBM Mainframe Forum: FAQ Register
 

How to pass a structure to external procedure in PLI.


IBM Mainframe Forums -> PL/I & Assembler
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
Pedro

Global Moderator


Joined: 01 Sep 2006
Posts: 2547
Location: Silicon Valley

PostPosted: Tue Jan 19, 2016 7:05 am
Reply with quote

I am fairly new to PLI. I beg your indulgence.

Almost the same situation as here:
ibmmainframes.com/viewtopic.php?t=52107

But I cannot get it to work! Depending on what I try, I get 0Cx. This code gets an 0C7.

The calling program is:
Code:
 PLITST1: PROC OPTIONS(MAIN) REORDER;               
 Dcl SYSPRINT         File Stream Output Print;     
 Dcl 1 ptrs union,                                 
       5 TESTAREA_ptr  Ptr,                         
       5 TESTAREA_char char(4);                     
 Dcl 1 TESTAREA     Ctl,                           
       5 ttl_id        char(8),                     
       5 ttl_message   char(25);                   
 Dcl TTL_IDC        char(8) INIT('TESTAREA') Static;
 Dcl PLITST2 External Entry (pointer);             
                                                   
 Open File(SYSPRINT) Pagesize(32000) Linesize(132);
 Fetch PLITST2;                                     
 Allocate TESTAREA;                                 
 TESTAREA_ptr    = Addr(TESTAREA);                 
 TESTAREA        = '';                             
 TESTAREA.ttl_id = ttl_idC;                         
                                                   
 PUT SKIP LIST('title id ' ||  TESTAREA.ttl_id   );
 PUT SKIP list('testarea_ptr=' || TESTAREA_char);   
                                                   
 Call PLITST2( TESTAREA_ptr );                     
                                                   
 PUT SKIP LIST('after call  ' || ttl_message );     
                                                   
 Free TESTAREA;                                     
 Release PLITST2;                                   
 Close File(Sysprint);                             
                                                   
 END PLITST1;                                       


I use the UNION only to dump out the pointer.

The called routine is:
Code:
 PLITST2: PROC( TESTAREA_ptr   ) reorder;     
                                               
 Dcl     TESTAREA_ptr  Ptr;                   
                                               
 Dcl 1 TESTAREA       BASED(TESTAREA_ptr),     
        5 ttl_id                   char(8),   
        5 ttl_message              char(25);   
                                               
 ttl_message = 'got to PLITST2';               
                                               
 END PLITST2;     


What am I doing wrong?
Back to top
View user's profile Send private message
Pedro

Global Moderator


Joined: 01 Sep 2006
Posts: 2547
Location: Silicon Valley

PostPosted: Tue Jan 19, 2016 7:10 am
Reply with quote

I am using FETCH to load the external routine. The routines are compiled separately and are separate load modules.
Back to top
View user's profile Send private message
Pedro

Global Moderator


Joined: 01 Sep 2006
Posts: 2547
Location: Silicon Valley

PostPosted: Tue Jan 19, 2016 7:13 am
Reply with quote

This is also similar to ibmmainframes.com/viewtopic.php?t=63421
in that I issue FETCH and get 0C7. Is there a trick to using FETCH?
Back to top
View user's profile Send private message
Pedro

Global Moderator


Joined: 01 Sep 2006
Posts: 2547
Location: Silicon Valley

PostPosted: Tue Jan 19, 2016 7:27 am
Reply with quote

After further reading: The PROC statement on the called routine needs to specify fetchable:
Code:

 PLITST2: PROC( TESTAREA_ptr   ) reorder OPTIONS(FETCHABLE); 
                                                             
Back to top
View user's profile Send private message
Nic Clouston

Global Moderator


Joined: 10 May 2007
Posts: 2455
Location: Hampshire, UK

PostPosted: Tue Jan 19, 2016 7:39 pm
Reply with quote

No need to declare SYSPRINT or open it or close it - the PL/1 environment will do that for you and may write messages there before the program is even invoked so you might actually destroy messages (so we were told in our PL/1 education in IBM way back when).

Apart from that I cannot help.
Back to top
View user's profile Send private message
prino

Senior Member


Joined: 07 Feb 2009
Posts: 1306
Location: Vilnius, Lithuania

PostPosted: Wed Jan 20, 2016 12:23 am
Reply with quote

1) You should declare anything you use, even SYSPRINT AND SYSIN!

2) Enterprise PL/I will actually print pointers in HEX format, no need for any character overlays.

3) "FETCHABLE" never used to be required, I doubt that it is now, as it would have broken zillions of programs...

Will give the code a try later.
Back to top
View user's profile Send private message
Pedro

Global Moderator


Joined: 01 Sep 2006
Posts: 2547
Location: Silicon Valley

PostPosted: Wed Jan 20, 2016 4:48 am
Reply with quote

Quote:
3) "FETCHABLE" never used to be required, I doubt that it is now, as it would have broken zillions of programs...

It definitely fails if it is not there and works if it is there, with no other changes. Maybe there is some other combination of statements that will make it work, but in my simple example, "FETCHABLE" is required.
Back to top
View user's profile Send private message
Pedro

Global Moderator


Joined: 01 Sep 2006
Posts: 2547
Location: Silicon Valley

PostPosted: Wed Jan 20, 2016 7:24 am
Reply with quote

From the PLI Programming Guide:
Quote:
OPTIONS(FETCHABLE) should be specified on the PROCEDURE statement of the fetched routine if there is no ENTRY card provided during the link-edit step.


I removed the OPTIONS(FETCHABLE) and changed my link edit to have an ENTRY statement:
Code:
  INCLUDE  OBJLIB(PLITST2)   
  ENTRY           PLITST2   
  NAME            PLITST2(R)

This worked! I think I will go with this, rather than the OPTIONS()
Back to top
View user's profile Send private message
Pedro

Global Moderator


Joined: 01 Sep 2006
Posts: 2547
Location: Silicon Valley

PostPosted: Sat Jan 23, 2016 12:17 am
Reply with quote

an additional note:
As I tried to implement this in my production module, I failed to add the FETCH and RELEASE statements to the calling program. In that case, PLI wants the called program to be included in the composite load module.

To have a separate load module, you need to specify FETCH and RELEASE.
Back to top
View user's profile Send private message
View previous topic :: :: View next topic  
Post new topic   Reply to topic View Bookmarks
All times are GMT + 6 Hours
Forum Index -> PL/I & Assembler

 


Similar Topics
Topic Forum Replies
No new posts How to pass the PARM value to my targ... COBOL Programming 8
No new posts Dynamically pass table name to a sele... DB2 2
No new posts how to use Tso outtrap external function All Other Mainframe Topics 8
No new posts Invoke stored procedure via batch JCL. DB2 2
No new posts pass data as symbolic parameter from ... CLIST & REXX 2
Search our Forums:

Back to Top