× 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.



Hi Doug,

QPMLPMGT became available in V5R3, yet I must still support customers
on releases prior to that.
When my customer on V5R2 attempts to run this program, they receive:
CPD0192: Service program QPMLPMGT not found.

I can think of three ways to solve this problem. These are alternatives to one another, you don't need to do them all:

IF DEFINED ALTERNATIVE
-----------------------
One simple approach is to use /if defined in the source code, and compile the code separately for V5R2 vs V5R3. It's a pain in the butt to do a different build for different releases, but it should work. For example:

/if defined(*V5R3M0)
D GetLparInfo PR 10I 0 EXTPROC('dlpar_get_info')
D Receiver 344
D Format 10I 0 Value
D RcvrLen 10I 0 Value

MONITOR;
RtnValue = GetLparInfo(Receiver:Format:RcvrLen);
ON-ERROR;
RtnValue = 0;
ENDMON;

/else
RtnValue = 0;
/endif

When compiled with a V5R3 or later compiler, this code will compile in the call to GetLparInfo. when compiled on a V5R2 compiler (including TGTRLS(V5R2M0)) this code will simply set RtnValue to 0, and not try to call the routine.


*PGM WRAPPER ALTERNATIVE
------------------------
Another relatively simple solution is to create a *PGM object (as opposed to a *SRVPGM) that takes parameters for the API, calls it, and returns the result. For example, write the following standalone RPG program:

H DFTACTGRP(*NO)

D LPARINFO PR ExtPgm('LPARINFO')
D Receiver 65535a options(*varsize)
D Format 10i 0 const
D RcvrLen 10i 0 const
D RtnValue 10i 0
D LPARINFO PI
D Receiver 65535a options(*varsize)
D Format 10i 0 const
D RcvrLen 10i 0 const
D RtnValue 10i 0

D GetLparInfo PR 10I 0 EXTPROC('dlpar_get_info')
D Receiver 65535a options(*varsize)
D Format 10I 0 Value
D RcvrLen 10I 0 Value
/free

MONITOR;
RtnValue = GetLparInfo(Receiver:Format:RcvrLen);
ON-ERROR;
RtnValue = 0;
ENDMON;

return;

/end-free

Then have the caller do something like this:

if release >= 'V5R3M0';
LPARINFO( MyRcvr
: MyFmt
: %size(MyRcvr)
: RetVal );
endif;

Since the *PGM wrapper is never called on earlier releases, you won't have a problem...


DYNAMIC *SRVPGM BINDING
------------------------
Finally... if you really want to do what you suggested, and dynamically call the API, you CAN do so, but it'll involve manually resolving the service program, manually activating it, manually getting a pointer to it's exported procedure, and finally, calling it. This involves:

a) Call the QLICVTTP API to get the hex object type for a *SRVPGM.

b) Call the RSLVSP2 MI builtin to resolve a system pointer to the *SRVPGM object. In RPG, you can define your system pointer as a procptr.

c) Call the QleActBndPgm() API to activate the service program.

d) Call the QleGetExp() API to get a procedure pointer to the dlpar_get_info() procedure within the service program.

e) Call your GetLparInfo prototype, but have the Extproc() point to the procedure pointer.

That type of coding is not for the feint-of-heart... I'm not sure that I'd recommend it, since I'm not sure that it'll provide any benefits above and beyond the simpler methods I mentioned above. But it's pretty cool that it's possible :)



As an Amazon Associate we earn from qualifying purchases.

This thread ...

Follow-Ups:
Replies:

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.