View previous topic :: View next topic
|
Author |
Message |
dejunzhu
Active User
Joined: 08 May 2008 Posts: 390 Location: China
|
|
|
|
hi,
I want to call a CICS statement imbedded subprogram, how can I achieve this ?
I mean, using 'CALL', instead of 'LINK' or 'XCTL'.
backgroud:
I have a copybook which contains record CMLCHLIN , and the copybook is copied in LINKAGE SECTION of main program program,
as I cannot use below statement:
Code: |
set lk-pointer to ADDRESS OF CMLCHLIN |
,
I have to use below statement instead:
Code: |
CALL WK-SUBPGM-CMSSEADR USING ADDRESS OF CMLCHLIN
CMLSEADR-REC (some other parameters...) |
as the parameter of subprogram contains more than one parameters, I have not thought out a better way than using 'CALL...USING parm1, parm2...' STATEMENT
but my test fails on above call....
is there a good solution if I want to transfer the address of a operand defined in LINKAGE SECTION into a CICS embeded subprogram?
by the way, the subprogram contains CICS statement because I have to take advantage of 'GETMAIN' CICS statement to allocate memory dynamically within it. There is no such equivalent statement in COBOL, right? |
|
Back to top |
|
|
dejunzhu
Active User
Joined: 08 May 2008 Posts: 390 Location: China
|
|
|
|
I have modified the main program to use DFHEIBLK and DFHCOMMAREA as the first two parameters in the CALL statement, but it still didn't work... |
|
Back to top |
|
|
Peter cobolskolan
Active User
Joined: 06 Feb 2012 Posts: 104 Location: Sweden
|
|
|
|
Quote: |
but it still didn't work... |
How do you think one could debug that? |
|
Back to top |
|
|
dbzTHEdinosauer
Global Moderator
Joined: 20 Oct 2006 Posts: 6966 Location: porcelain throne
|
|
Back to top |
|
|
Bill O'Boyle
CICS Moderator
Joined: 14 Jan 2008 Posts: 2501 Location: Atlanta, Georgia, USA
|
|
|
|
Please post the first 10-20 lines of the called program's PROCEDURE DIVISION. Don't forget to use code tags.
You've got something mixed up.... |
|
Back to top |
|
|
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
If you are CALLing a program which uses CICS commands, that program gets translated to have DFHEIBLK and DFHCOMMAREA as the first two items on the PROCEDURE DIVISION USING, so they must also, in the correct order, be the first two items on the CALL USING.
Why can't you do a SET, do you think?
What is so wrong, do you feel, with ordinary CALL USING? If you need then the address of an item passed to the called program, you can get it in the called program just as easily, if only you could get the SET to work.
What doesn't work in your program. You've mentioned it twice, but omitted even the slightest detail. |
|
Back to top |
|
|
Bill O'Boyle
CICS Moderator
Joined: 14 Jan 2008 Posts: 2501 Location: Atlanta, Georgia, USA
|
|
|
|
Bill,
FWIW, you can have a module that can be CALLED or LINKED-TO and you can determine this programmatically.
As the first line of code, check the value of EIBRSRCE.
If it's equal to the sub-program's name, then you've been LINKED-TO and you need to access the commarea. Otherwise, you've been CALLED and (in our case), we had to access the 3rd-parm as a substitute for the commarea and leave the caller's commarea intact.
Regards, |
|
Back to top |
|
|
dejunzhu
Active User
Joined: 08 May 2008 Posts: 390 Location: China
|
|
|
|
in main program:
linkage section:
Code: |
*
LINKAGE SECTION.
01 DFHCOMMAREA.
COPY CMLCMPTR REPLACING ==:CMLCMPTR:== BY ==CMLCMPTR==.
COPY CMLCHLIN REPLACING
==:CMLCHLIN:== BY ==CMLCHLIN==.
* |
calling section code:
Code: |
CALL WK-SUBPGM-CMSSEADR USING DFHEIBLK
DFHCOMMAREA
ADDRESS OF CMLCHLIN
CMLSEADR-DB-BUFFER-NAME
CMLSEADR-DB-BUFFER-LEN
CMLSEADR-RET-CODE |
in called program:
Code: |
LINKAGE SECTION.
01 DFHCOMMAREA.
COPY CMLCMPTR REPLACING ==:CMLCMPTR:== BY ==CMLCMPTR==.
01 CMLSEADR-DB-BUFFER-PTR POINTER.
01 CMLSEADR-DB-BUFFER-NAME PIC X(8).
01 CMLSEADR-DB-BUFFER-LEN PIC 9(9) COMP.
01 CMLSEADR-RET-CODE PIC 9(4).
COPY CMTAPCMA REPLACING
==:CMLAPCMA:== BY ==CMLAPCMA==.
PROCEDURE DIVISION USING DFHEIBLK
DFHCOMMAREA
CMLSEADR-DB-BUFFER-PTR
CMLSEADR-DB-BUFFER-NAME
CMLSEADR-DB-BUFFER-LEN
CMLSEADR-RET-CODE.
0000-BEG-RTN.
EXEC CICS HANDLE
ABEND
LABEL(9100-HANDLE-ABEND)
END-EXEC
EXEC CICS HANDLE
CONDITION
NOSTG (9200-HANDLE-NOSTG)
EXEC CICS
GETMAIN SET (CMLAPCMA-DB-BUFF-PTR (WK-BUF-IDX) )
FLENGTH (CMLSEADR-DB-BUFFER-LEN)
INITIMG (WK-INITIAL-VALUE)
NOSUSPEND
END-EXEC |
in my subprogram, I just want to dynamically allocate memory and set the address to a linkage section variable in main program, so that the linkage section variable can be allocated to the new allocated memory...
I did not find any COBOL function that can allocate memory dynamically, so I have to use ' GETMAIN' cics command...
If you have a better solution, please advise, appreciate ... |
|
Back to top |
|
|
Peter cobolskolan
Active User
Joined: 06 Feb 2012 Posts: 104 Location: Sweden
|
|
|
|
To me it seems that you are complicating your programming, but as you dont show all the code, its not easy to understand what you really are doing.
Quote: |
I have a copybook which contains record CMLCHLIN , and the copybook is copied in LINKAGE SECTION of main program program |
Why in Linkage ?
Quote: |
I did not find any COBOL function that can allocate memory dynamically, so I have to use ' GETMAIN' cics command...
|
Is the CICS Getmain not good enough for a CICS program ?
Why are you using Handle Condition and not Resp Option ?
You are also using Handle Abend. Why? |
|
Back to top |
|
|
dbzTHEdinosauer
Global Moderator
Joined: 20 Oct 2006 Posts: 6966 Location: porcelain throne
|
|
|
|
1. is the main cobol program invoked in batch or cics?
2. what does the procedure division using statement look like in the main program?
3. cobol CALLed modules in CICS operate under a different Task Control Block as CICS modules in the CALL Chain.
as bill said, your CALL to the cics subprogram sucks.
replace the "address of " with a working storage pointer.
if the COBOL CALL to a CICS module actually works,
then upon return, set the ADDRESS of the copy book to the pointer.
if it is a copybook, and you have to obtain memory (and the same amount every time)
stop being an idiot and define this in working-storage of the mainprogram
and stop this getmain bullshit.
i provided links to LE, which will obtain storage for a task.
i personnally do not think that you can invoke a cics module via a cobol call
and expect cics to process any api calls in the submodule.
but, for argument let us say you can,
you still need to change your passed parms.
pass the pointer to the submodule
and set the linkage section structure to the address of ptr
upon return from the memory acquisition. |
|
Back to top |
|
|
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
dbzTHEdinosauer wrote: |
as bill said, your CALL to the cics subprogram sucks.
replace the "address of " with a working storage pointer.
|
In a post presumably lost in the "outage". I was thinking I'd not posted it, but if dbz read it, I must have done... |
|
Back to top |
|
|
dbzTHEdinosauer
Global Moderator
Joined: 20 Oct 2006 Posts: 6966 Location: porcelain throne
|
|
|
|
sorry bill, it was not an 'actual' but rather a 'paraphrased' quote.
there are two problems in this topic, assuming the main cobol program is COBOL CALLed from a CICS module.
1. don't think you can - COBOL CALL module A from CICS module 1 (this you can do)
- COBOL CALL CICS module 2 from module A and expect CICS API's to function
2. even if 1 is ok (that means that I am wrong about the CALL stuff)
Module A should have a WORKING-STORAGE Pointer,
which is passed to CICS Module 2, populated by a CICS GETMAIN,
the return to Module A, which SETS THE ADDRESS OF linkage-structure TO working-storage Pointer populated by CICS module 2. |
|
Back to top |
|
|
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
No problem with the style of the quote, dbz :-)
The CALL x USING ADDRESS OF y behaves like this:
Cobol tucks tucks the address of your item in a little piece of storage that you have no accesss to. Passing it as a parameter is fine, but attempting to change it in the called program is entirely pointless, as there is no lasting relationship between the tucked-away storage and your definition.
In this instance, since you don't have any storage for that yet, the address would be NULL anyway, so not only useless to the calling program, useless to the called program as well.
Dbz has "pointed" you in the right direction for a fix of that.
I also asked to see the COMPILE LISTING with the PROCEDURE DIVISIONS USING, as you previously showed something which is a source listing yet had the parameters on which the CICS translation would include... |
|
Back to top |
|
|
Peter cobolskolan
Active User
Joined: 06 Feb 2012 Posts: 104 Location: Sweden
|
|
|
|
An example:
Code: |
000100 Id Division.
000200 Program-Id. TSTPGM1.
000300 Data Division.
000400 Working-Storage Section.
000500 01 Pgmname Pic X(08) Value 'TSTPGM2'.
000600 01 ThePointer Pointer.
000700 01 TheLength Pic 9(08) Binary.
000800 01 TheCommarea Pic X(1).
000900 Linkage Section.
001000 01 TheStructure.
001100 05 Element1 Pic X(10).
001200 05 Element2 Pic X(10).
001300 05 Element3 Pic X(10).
001400 05 Element4 Pic X(10).
001500
001600 Procedure Division.
001700 Move Length of TheStructure to TheLength
001800 Call Pgmname Using
001900 DFHEIBLK
002000 TheCommarea
002100 ThePointer
002200 TheLength
002300 Set Address of TheStructure to ThePointer
002400 * Just for testing
002500 Move 'Element1' to Element1
002600 Exec CICS Send
002700 From(TheStructure)
002800 End-Exec
002900 Exec CICS
003000 Return
003100 End-Exec
003200 .
003300 *------------------------------------------
003400 Id Division.
003500 Program-Id. TSTPGM2.
003600 Data Division.
003700 Working-Storage Section.
003800 Linkage Section.
003900 01 Dfhcommarea Pic x(1).
004000 01 ThePointer Pointer.
004100 01 TheLength Pic 9(08) Binary.
004200 Procedure Division Using
004300 DFHEIBLK
004400 DFHCOMMAREA
004500 ThePointer
004600 TheLength
004700 .
004800 Exec CICS Getmain
004900 FLength(TheLength)
005000 Set (ThePointer)
005100 Initimg('X')
005200 End-Exec
005300 Exit Program
005400 .
005500 End Program TstPgm2.
005600 End Program TstPgm1.
****** **************************** Bottom of Data ***** |
|
|
Back to top |
|
|
dbzTHEdinosauer
Global Moderator
Joined: 20 Oct 2006 Posts: 6966 Location: porcelain throne
|
|
|
|
Peter cobolskolan,
the imbedded stuff works,
but does not resolve the problem.
a non-cics COBOL (not part of the CALLing Load module) module
is invoked from a CICS COBOL module via a COBOL CALL
then the COBOL Module CALLS a CICS Module (again separate load module)
does the GETMAIN and then returns to the COBOL Module
which plays with the area (and I hope CALLS the CICS Module again and FREEs the memory!!!!!)
then eventually returns to the CICS Mainprogram. |
|
Back to top |
|
|
dbzTHEdinosauer
Global Moderator
Joined: 20 Oct 2006 Posts: 6966 Location: porcelain throne
|
|
|
|
back in my younger days,
and since it would only take 10 minutes to test,
i would try putting the CICS LINK getmain-module
in a copybook and then run it thru the CICS translator generating a translated copybook,
which i would then copy into the pure COBOL module.
i would not be surprised if the RETURN from the getmain-module ended up in the pure cobol module.
and have a batch copy of the copybook for calls to a cobol module that does an LE call for memory. |
|
Back to top |
|
|
dejunzhu
Active User
Joined: 08 May 2008 Posts: 390 Location: China
|
|
|
|
below is a part of compile list...
Called sub-program compile list:
linkage section
Code: |
SDSF OUTPUT DISPLAY CCMONL JOB04419 DSID 102 LINE 346 COLUMNS 02- 81
COMMAND INPUT ===> SCROLL ===> CSR
000270 LINKAGE SECTION.
000271 01 dfheiblk.
000272 02 eibtime comp-3 pic s9(7).
000273 02 eibdate comp-3 pic s9(7).
000274 02 eibtrnid pic x(4).
000275 02 eibtaskn comp-3 pic s9(7).
000276 02 eibtrmid pic x(4).
000277 02 dfheigdi comp pic s9(4).
000278 02 eibcposn comp pic s9(4).
000279 02 eibcalen comp pic s9(4).
000280 02 eibaid pic x(1).
000281 02 eibfn pic x(2).
000282 02 eibrcode pic x(6).
000283 02 eibds pic x(8).
000284 02 eibreqid pic x(8).
000285 02 eibrsrce pic x(8).
PP 5655-S71 IBM Enterprise COBOL for z/OS 4.2.0 CMSSEADR Date 05
LineID PL SL ----+-*A-1-B--+----2----+----3----+----4----+----5----+----6---
000286 02 eibsync pic x(1).
000287 02 eibfree pic x(1).
000288 02 eibrecv pic x(1).
000289 02 eibfil01 pic x(1).
000290 02 eibatt pic x(1).
000291 02 eibeoc pic x(1).
000292 02 eibfmh pic x(1).
000293 02 eibcompl pic x(1).
000294 02 eibsig pic x(1).
000295 02 eibconf pic x(1).
000296 02 eiberr pic x(1).
000297 02 eiberrcd pic x(4).
000298 02 eibsynrb pic x(1).
000299 02 eibnodat pic x(1).
000300 02 eibresp comp pic s9(8).
000301 02 eibresp2 comp pic s9(8).
000302 02 eibrldbk pic x(1).
000303 01 DFHCOMMAREA.
000304 COPY CMLCMPTR REPLACING ==:CMLCMPTR:== BY ==CMLCMP
000305C 05 CMLCMPTR POINTER.
000306 01 CMLSEADR-DB-BUFFER-PTR POINTER.
000307 01 CMLSEADR-DB-BUFFER-NAME PIC X(8).
000308 01 CMLSEADR-DB-BUFFER-LEN PIC 9(9) COMP.
000309 01 CMLSEADR-RET-CODE PIC 9(4). |
there is no expansion for PROCEDURE DIVISION USING statement:
Code: |
000454 *********************************************************
000455 * PROCEDURE DIVISION
000456 *********************************************************
PP 5655-S71 IBM Enterprise COBOL for z/OS 4.2.0 CMSSEADR Date 05
LineID PL SL ----+-*A-1-B--+----2----+----3----+----4----+----5----+----6---
000457 PROCEDURE DIVISION USING DFHEIBLK
000458 DFHCOMMAREA
000459 CMLSEADR-DB-BUFFER-PTR
000460 CMLSEADR-DB-BUFFER-NAME
000461 CMLSEADR-DB-BUFFER-LEN
000462 CMLSEADR-RET-CODE.
000463 *-------------------------------------------------------- |
LINKAGE SECTION of main program shows below:
Code: |
SDSF OUTPUT DISPLAY CCMONL JOB04422 DSID 102 LINE 499 COLUMNS 02- 81
COMMAND INPUT ===> SCROLL ===> CSR
000417 LINKAGE SECTION.
000418 01 dfheiblk.
000419 02 eibtime comp-3 pic s9(7).
000420 02 eibdate comp-3 pic s9(7).
000421 02 eibtrnid pic x(4).
000422 02 eibtaskn comp-3 pic s9(7).
000423 02 eibtrmid pic x(4).
000424 02 dfheigdi comp pic s9(4).
000425 02 eibcposn comp pic s9(4).
000426 02 eibcalen comp pic s9(4).
000427 02 eibaid pic x(1).
000428 02 eibfn pic x(2).
000429 02 eibrcode pic x(6).
000430 02 eibds pic x(8).
000431 02 eibreqid pic x(8).
000432 02 eibrsrce pic x(8).
000433 02 eibsync pic x(1).
000434 02 eibfree pic x(1).
000435 02 eibrecv pic x(1).
000436 02 eibfil01 pic x(1).
000437 02 eibatt pic x(1).
000438 02 eibeoc pic x(1).
000439 02 eibfmh pic x(1).
000440 02 eibcompl pic x(1).
000441 02 eibsig pic x(1).
000442 02 eibconf pic x(1).
000443 02 eiberr pic x(1).
000444 02 eiberrcd pic x(4).
000445 02 eibsynrb pic x(1).
000446 02 eibnodat pic x(1).
000447 02 eibresp comp pic s9(8).
000448 02 eibresp2 comp pic s9(8).
000449 02 eibrldbk pic x(1).
000450 01 DFHCOMMAREA.
000451 COPY CMLCMPTR REPLACING ==:CMLCMPTR:== BY ==CMLCMP
000452C 05 CMLCMPTR POINTER. |
I have read your comment on this issue, but I want to verify it myself via test...
but I cannot find where my program is wrong... the main program just abended when call this CICS statement imbeded subprogrm.
I have paste the compile list on your request, if any other information needed, please advise. thanks. |
|
Back to top |
|
|
Peter cobolskolan
Active User
Joined: 06 Feb 2012 Posts: 104 Location: Sweden
|
|
|
|
Try define/install the called program with CEDA. |
|
Back to top |
|
|
dejunzhu
Active User
Joined: 08 May 2008 Posts: 390 Location: China
|
|
|
|
I followed Dick Brenholtz 's advice, and the program is called successfully.
Thanks for your advice on this topic. |
|
Back to top |
|
|
dbzTHEdinosauer
Global Moderator
Joined: 20 Oct 2006 Posts: 6966 Location: porcelain throne
|
|
|
|
earlier this century,
I stumbled upon the obvious phenomenon that
if you take a (db2/cics/mqs) API and put it in a copy book
translate the copybook (run it thru the appropriate pre-compiler)
and COPY that translated copybook into a pgm that was compiled without pre-compiler,
and if the program was invoked in the appropriate environment,
(CALLed by a CICS module or by a module that was already connected to db2/mqs)
the service (db2/cics/mqs service) could be CALLed (the translated copybook) successfully.
which obviously ended with no end of mischief.
i know/knew that cics sets-up different types of TCB's,
one type for a COBOL CALL invoked module
and
another type for a CICS XCTL/LINK invoked module.
always worried that the different TCB's would get me into trouble
while executing 'foreign' commands. (CICS API CALL from a COBOL CALL invoked module).
but it seems that allocated memory for a task,
is just that,
and that worked.
never had to do much else with the CICS stuff,
mqs was really tricky because the STUBs are necessary
db2 was basically getvariables and timestamps,
(but the db2 required additiionally tricky copybooks.
all host references were to linkage, so that worked out)
Dejunzhu,
keep experimenting and pushing the 'bounds'. and have fun. |
|
Back to top |
|
|
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
Bill Woodger wrote: |
[...]
The CALL x USING ADDRESS OF y behaves like this:
Cobol tucks tucks the address of your item in a little piece of storage that you have no accesss to. Passing it as a parameter is fine, but attempting to change it in the called program is entirely pointless, as there is no lasting relationship between the tucked-away storage and your definition.
In this instance, since you don't have any storage for that yet, the address would be NULL anyway, so not only useless to the calling program, useless to the called program as well.
[...]
|
Sorry dejunzhu, I got the above wrong. The description I gave for how it works is for BY CONTENT on the USING. You have, implicitly, BY REFERENCE.
For BY REFERENCE, with an item in the Linkage Section, you can amend the ADDRESS OF in a called program.
There is mention in the manual that "identifier-2" should have addressability prior to the CALL, but it is not clear if this comment applies to the "identifier-2" in the ADDRESS OF. It is also potentially one of those situations where "must" in the Cobol manual means "should".
Now, for problem determination, changing the address of something directly (the program is passing the actual BLL Cell) in another module does not sound like such a good idea to me. It should work, but will have made the logic more obscure.
If you ever do it that way, make sure it is clearly documented/commented for/in the calling and called modules, please.
The clearer way to do it, as dbz already suggested on this point, is to set to a POINTER in the caller, change the value of that in the called, then set the address from the POINTER in the caller when you get back after the call. |
|
Back to top |
|
|
|