× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.


  • Subject: RE: OO in RPG
  • From: "Smith, Nelson" <NSmith@xxxxxxxxxxx>
  • Date: Wed, 6 Dec 2000 09:37:52 -0500

Jon,

In my trigger procedures I use _RSLVSP2 to get a system pointer to a given
service program.  Then, use that system pointer with QleActBndPgm to
activate the service program and get an Activation Mark back (whatever that
is....) and then finally, use the activation mark with QleGetExp to get a
procedure pointer to the actual procedure name. Once the procedure pointer
has been obtained, it can be used in a normal CALLP operation.   

This was worked out several years ago with a lot of fine help from Barbara.
I don't understand all the internals, but it works like a champ and allows
me to have completely dynamic triggers controlled by entries in a Database
Control file containing the names of the service program and trigger
procedure I want to use for any given database file.  The database files
themselves all have a generic trigger program attached to them which does
nothing but call a master procedure which in turn checks the control file
for the names and then calls this procedure to obtain a pointer to the
actual trigger procedure to be used for that specific file/library
combination.  This allows tremendous flexibility.  For example, different
trigger procedures can be used on the same file when it is in different
libraries (such as QA vs. Production) and once established, the triggers
never have to be added or removed from the base file.  All changes can be
implemented by changes to the control file or the procedures themselves.

For anyone who wishes to try it (including the gentleman), the procedure
code follows and again, kudos to Barbara Morris for all of her fine help
with the details.  I apologize for the spacing, my cut and paste is not the
best.

 P**************************************************************************

 P RtvProcPtr      B                   EXPORT

 P**************************************************************************

 P*                 P R O C E D U R E                                      
 P*                                                                        
 P*  Name.......... RtvProcPtr

 P*                                                                        
 P*  Purpose....... To retrieve the address of a procedure exported from    
 P*                      a service program.

 P*                                                                        
 P*  Requires...... The name of the service program, the name of the       
 P*                      procedure, and optionally, a procedure pointer for

 P*                      the return value.

 P*                                                                        
 P*  Returns....... A pointer to the procedure as both a return value and 
 P*                     the optional third parameter (so CALLP may be used).

 P*                                                                        
 P*  Service Pgm... Procs_Ptrs                                             
 P*                                                                        
 P*  Binding Dir... LinBndDir                                              
 P*

 P*  Keywords...... Pointer Export Procedure                                
 P*                                                                        
 P*  Sample use.... EVAL  pProc  = RtvProcPtr(ServicePgm:'Proc_Name')

 P*                                                  or
 P*                        CALLP RtvProcPtr(ServicePgm:'Proc_Name':pProc)

 P*                                                                        
 P**************************************************************************

 

D*=================================================================== 
D* Procedure Initialization:
D*==================================================================== D
RtvProcPtr      PI              *   PROCPTR                                
D  Procedure                    30A   CONST

D  SrvPgmName                   10A   CONST

D  ReturnPtr                      *   PROCPTR OPTIONS(*NOPASS)

D*===================================================================
 

 
D*====================================================================
D* Data Structure to set object data:

D*====================================================================
D ObjectDS        DS

D  ObjectType                    2A   INZ(X'0203')

D  ObjectName                   30A

D  ObjReqAuth                    2A   INZ(X'0000')

D*====================================================================
 

 

D*====================================================================
D* Standalone fields:

D*==================================================================== D
SystemPtr       S               *   PROCPTR                                 
D ProcedurePtr    S               *   PROCPTR

D ActivationMark  S             10I 0 INZ( 0                              )

D ProcName        S             30A   INZ( *BLANKS                        )

D ProcNameLen     S             10I 0 INZ( 0                              )

D*====================================================================   
 

 

C**************************************************************************

C*                       M A I N L I N E                                   
C**************************************************************************

 

 * Get system pointer to the service program:

C                   EVAL      ObjectName    = SrvPgmName

 

C                   CALLB     '_RSLVSP2'

C                   PARM                    SystemPtr

C                   PARM                    ObjectDS

 

 * Then, activate the service program & get an activation mark back:

C                   CALLB     'QleActBndPgm'                  
C                   PARM                    SystemPtr         
C                   PARM                    ActivationMark    
C                   PARM                    *OMIT             
C                   PARM                    *OMIT             
C                   PARM                    *OMIT             
                                                              
 * Then, get a pointer to the procedure:                      
C                   EVAL      ProcName      = Procedure       
C     ' '           CHECKR    ProcName      ProcNameLen       
                                                              
C                   CALLB     'QleGetExp'                     
C                   PARM                    ActivationMark    
C                   PARM                    *OMIT             
C                   PARM                    ProcNameLen       
C                   PARM                    ProcName          
C                   PARM                    ProcedurePtr      
C                   PARM                    *OMIT             
C                   PARM                    *OMIT             
                                                              
 * Load up the return pointer if it was included in the parameters:

C                   IF        %PARMS        = 3

C                   EVAL      ReturnPtr     = ProcedurePtr

C                   ENDIF

 

C                   RETURN    ProcedurePtr

C**************************************************************************

C*                E N D   O F   M A I N L I N E                           *

C**************************************************************************

 

P RtvProcPtr      E

P**************************************************************************




        Jon, to persue your idea of a program that loads an array of
procedure pointers, do you know of a way to obtain a list of pointers to all
of the service program's exports at once, rather than just the named ones as
in the procedure shown above or would I have to first create a list of the
exported procedure names and get the pointers one-by-one?  Also, how would
you know what parameters are required with different procedure pointers in
the array when you go to use them?  In the case of my triggers above, they
all have the same parameter requirements, so it is not a problem. 


> -----Original Message-----
> From: Jon.Paris@hal.it [SMTP:Jon.Paris@hal.it]
> Sent: Tuesday, December 05, 2000 11:33 AM
> To:   RPG400-L@midrange.com
> Subject:      RE: OO in RPG
> 
> 
>  >> To obtain a truly dynamic procedure call that is not known at compile
> time
> you must you the special API's that permit you to force the activation of
> a
> service pgm and provide access to the procedures within.
> 
> Hi Peter,
> 
> one qualification and one question.
> 
> While it is true that the addresses must be known at compile time, it is
> _which_ program's compile time that is the issue.  For example, I can
> create a dynamically called program which establishes procedure pointers
> for all of the procedures it wishes to make available to the outside
> world.
> 
> This program has a mainline whose only purpose is to return to its caller
> an array of procedure pointers and their names.  This program can be
> dynamically called during the initialization phase.  Subsequently the
> procedure pointers are used to call the subprocedures in the "program".
> 
> By doing it this way the only program that needs to know the procedure
> addresses at compile time is the one that contains them - not exactly an
> arduous limitation!!  The other benefit is that the program itself is
> dynamically called to provide the pointers in the first place and because
> it is a dynamic call it can be called by variable name. Since it is only
> ever called once during the currency of the application, the performance
> of
> such a call is not an issue - of course it mustn't return with LR on
> <grin>.
> 
> As you can see considerable flexibility can be gained without the need to
> resort to the APIs.
> 
> That brings me to my question.  Which are the APIs involved?  I tried to
> find them the other day to answer a question from a "gentleman" on one of
> the lists who insisted that I was lying when I said it could be done.
> Because he'd been so darn rude I didn't put a lot of work into it, but I
> know they exist.  Can you help me out with the names?
> 
> Thanks muchly
> 
> 
> +---
> | This is the RPG/400 Mailing List!
> | To submit a new message, send your mail to RPG400-L@midrange.com.
> | To subscribe to this list send email to RPG400-L-SUB@midrange.com.
> | To unsubscribe from this list send email to RPG400-L-UNSUB@midrange.com.
> | Questions should be directed to the list owner/operator:
> david@midrange.com
> +---


************************************************************************************************************************************************************************************************************
This message originates from Lincare Holdings Inc. It contains information 
which maybe confidential or privileged and is intended only for the individual 
or entity named above.
It is prohibited for anyone else to disclose, copy, distribute or use the 
contents of this message. 
All personal messages express views solely of the sender, which are not to be 
attributed to Lincare Holdings Inc., and may not be copied or distributed 
without this disclaimer. 
If you received this message in error, please notify us immediately at 
MailAdmin@lincare.com or (800) 284-2006.
************************************************************************************************************************************************************************************************************
+---
| This is the RPG/400 Mailing List!
| To submit a new message, send your mail to RPG400-L@midrange.com.
| To subscribe to this list send email to RPG400-L-SUB@midrange.com.
| To unsubscribe from this list send email to RPG400-L-UNSUB@midrange.com.
| Questions should be directed to the list owner/operator: david@midrange.com
+---

As an Amazon Associate we earn from qualifying purchases.

This thread ...


Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.