Reputation:
I am trying to understand the meaning of the details that are displayed on using the DSPPGM command on a program.
Suppose command is as below:
DSPPGM PGM(SE046R) DETAIL(*ALL)
The information showed for Detail as *MODULE is as below:
Program . . . . . . . : SE046R Library . . . . . . . : HGBASQUA
Owner . . . . . . . . : QPGMR
Program attribute . . : RPGLE
Detail . . . . . . . . : *MODULE
Type options, press Enter.
5=Display description 6=Print description
Creation Optimization Debug
Opt Module Library Attribute Date Level Data
SE046R QTEMP RPGLE 06/28/17 *NONE *YES
What I don't understand here is why SE046R shows up as a module. as there is no object of this name with type MODULE.
Next comes the Service program details. Are the below ones the list of service programs bound to the program? Apart from SE045RS, everything seem to be some sort of system defined stuff?
Service
Program Library Activation Signature
QC2SYS QSYS *IMMED 000000000000000000009485A3A2A8A2
SE045RS *LIBL *IMMED A584A90E326C57B523D38F7C6803F7C4
QRNXIE QSYS *IMMED D8D9D5E7C9C540404040404040404040
QRNXUTIL QSYS *IMMED D8D9D5E7E4E3C9D34040404040404040
QRNXDUMP QSYS *IMMED D8D9D5E7C4E4D4D74040404040404040
QLEAWI QSYS *IMMED 44F70FABA08585397BDF0CF195F82EC1
Also, SE045RS is a service program which on doing a DSPSRVPGM command displays the SE045RM which i guess means that the service program consists of a MODULE by the name SE045RM.
There are procedure calls in SE046R to procedures defined within SE045RM. I undertand that perfectly but would it be possible the other way around? That is there is a procedure defined within SE046R, can i use it within a procedure defined inside the SE045RM module?
Update - 1:
Okay so the decision has been made to move the the procedure to SE045RM and whatever local variables that were being used within the procedure would now have to be passed as parameters. that would mean pretty much the below:
LongMsg = 'Program ' + %Trim(P_Program) +
' encountered a SQL error code ' +
%Char(P_SQLError01) + ' while trying to ' + %Trim(P_ActText) + ' for ' +
%char(Input_Company) + ':' + %trim(Input_Int_Hdr) + ':' +
%trim(Input_Order) + ':' + %char(Input_Line_Itm_Seq) + ':' +
%char(Input_Rel_Seq) + ':' + %trim(Input_VIN);
All the above fields are local to SE046R and would have worked perfectly inside that but now these would have to be passed as parameters to the Procedure. Question is passing as many parameters as above along with around 4 more a good practice? That would be around 13 parameters to the the Procedure call of SQLSoftError. Is this a good thing to do?
Upvotes: 1
Views: 819
Reputation: 11473
I just want to make one addendum to Charles' answer.
There are procedure calls in SE046R to procedures defined within SE045RM. I undertand that perfectly but would it be possible the other way around? That is there is a procedure defined within SE046R, can i use it within a procedure defined inside the SE045RM module?
Generally, no. If you want a procedure to be shared, it belongs in a *SRVPGM.
Generally because you can do it, but not with a bound call. You need to use a technique called a callback. In this case SE046R defines a procedure that is needed by a procedure in SE045RS. The procedure in SE046R is the callback procedure. SE046R would define a procedure pointer to the callback, and then would pass that procedure pointer to the procedure in SE045RS that needs to 'call back' into SE046R. One commonly used example of this is the qsort function in C. Qsort can sort any array because it uses a callback to tell it if two elements are equal or one is greater than the other. Qsort itself doesn't know the difference, and can't compare two pieces of the array, but the program that defined the array can know that information, and can do the comparison based on that knowledge. Ok I am rambling now. This is what calling a procedure by procedure pointer might look like:
dcl-s procptr Pointer(*proc);
dcl-pr MyProc;
parm1 ...
parm2 ...
end-pr;
dcl-pr proc ExtProc(procptr);
parm1 ...
parm2 ...
end-pr;
...
procptr = %paddr(MyProc);
...
proc(parm1: parm2);
The nice thing about a procedure pointer is that it can be passed as a parameter just like any other pointer, and on the other side used to call the procedure. An advantage that procedure pointers have over pointers in other languages is that they can only be used to reference procedures, not data, and vice versa. You can't take a procedure pointer and pass it to a data pointer and attempt to modify it like data. IBM i knows the difference and will throw an error.
Upvotes: 1
Reputation: 23783
What I don't understand here is why SE046R shows up as a module. as there is no object of this name with type MODULE.
ILE programs are always created from modules in a two step process.
CRTBNDxxx, used to create a *PGM object from a single source of the same name, is simply a shortcut that does both steps for you automagically.
Next comes the Service program details. Are the below ones the list of service programs bound to the program? Apart from SE045RS, everything seem to be some sort of system defined stuff?
Correct, the Qxxxx service programs in QSYS are system objects and are automatically bound in.
There are procedure calls in SE046R to procedures defined within SE045RM. I undertand that perfectly but would it be possible the other way around? That is there is a procedure defined within SE046R, can i use it within a procedure defined inside the SE045RM module?
Generally, no. If you want a procedure to be shared, it belongs in a *SRVPGM.
Upvotes: 2