×

Good News Everybody!

The new search engine is LIVE!

Please report any problems to david (at) midrange.com.




Hello,

Yes, it is possible to call any program with any number of parameters,
including pointers.

This is how you do it:

First, prototype the machine instruction, CALLPGMV:

D callProgram PR extproc('_CALLPGMV')
D programAddress...
D * procptr const
D argVector * value
D argCount 10U 0 value

Then, create this function:

//
=======================================================================
// Function getProgramAddress:

//
=======================================================================
// This function returns the system address of a program object or
*null
// if not found or error occurs.

//
=======================================================================
P getProgramAddress...

P B

D PI * procptr

D inProgramName...

D 10A const
D inProgramLibrary...

D 10A const
D options(*nopass)



//
=======================================================================
// - Local Data Types -

//
=======================================================================


D ErrorCode DS
D BytesProvide 10I 0 Inz(%Size(ErrorCode))
D BytesAvail 10I 0
D ExceptID 7
D Reserved 1
D ExceptData 240

D typeSystemPointer...
D S * procptr based(@)



//
=======================================================================
// - External Procedure Prototypes -

//
=======================================================================
D resolveUnqualifiedSystemPointer...

D PR extproc('_RSLVSP2')

D systemPointer like(typeSystemPointer)

D resolution like(resolutionTemplate) const



D resolveQualifiedSystemPointer...

D PR extproc('_RSLVSP4')

D systemPointer like(typeSystemPointer)

D resolution like(resolutionTemplate) const

D libraryPointer...

D like(typeSystemPointer) const



//
=======================================================================
// - Local Data Structures -

//
=======================================================================
D resolutionTemplate...

D DS qualified

D typeCode 1A

D subtypeCode 1A

D objectName 30A

D authority 2A inz(x'0000')



D activationInformation...

D DS qualified align

D bytesReturned 10I 0 inz(%size(activationInformation))

D bytesAvailable...

D 10I 0 inz

D 8A inz(*allx'00')
RESERVED
D activationGroupMark...

D 10I 0

D activationMark...

D 10I 0

D 7A inz(*allx'00')
RESERVED
D flags 1A

D 1A inz(*allx'00')
RESERVED


//
=======================================================================

// - Local Constants -

//
=======================================================================

// return codes for exportTypeFound parameter for getExport procedure

D EXPORT_TYPE_NOT_FOUND...

D C 0

D EXPORT_TYPE_PROCEDURE_FOUND...

D C 1

D EXPORT_TYPE_DATA_FOUND...

D C 2

D EXPORT_TYPE_NOT_ACCESSIBLE...

D C 3



//
=======================================================================
// - Local Procedure Parameter Variables -

//
=======================================================================
D lProgramLibrary...

D S like(inProgramLibrary)

D inz('*LIBL')



//
=======================================================================
// - Local Variables -

//
=======================================================================
D serviceProgramProcedureNameLength...

D S 10I 0 inz

D libraryPointer S like(typeSystemPointer)

D serviceProgramPointer...

D S like(typeSystemPointer)

D activationMark S 10I 0 inz

D procedurePointer...

D S * procptr inz(*null)

D exportTypeFound...

D S 10I 0 inz(EXPORT_TYPE_NOT_FOUND)

/free

monitor;

// Get the program library - if it is not passed, *LIBL is

// used.

if %parms >= 2;

lProgramLibrary = inProgramLibrary;

endif;



//
-------------------------------------------------------------------
// Get the pointer to the service program

//
-------------------------------------------------------------------
// If library is generic *LIBL (only generic allowed)
----------------
if lProgramLibrary = '*LIBL';

// Obtain pointer to service program procedure without context
----
resolutionTemplate.typeCode = x'02'; // program

resolutionTemplate.subtypeCode = x'01';

resolutionTemplate.objectName = inProgramName;

resolveUnqualifiedSystemPointer

(serviceProgramPointer : resolutionTemplate);

else;

// Obtain pointer to library
--------------------------------------
resolutionTemplate.typeCode = x'04'; // context

resolutionTemplate.subtypeCode = x'01'; // access
group
resolutionTemplate.objectName = lProgramLibrary;

resolveUnqualifiedSystemPointer

(libraryPointer : resolutionTemplate);



// Obtain pointer to service program procedure with context
-------
resolutionTemplate.typeCode = x'02'; // program

resolutionTemplate.subtypeCode = x'01'; // module

resolutionTemplate.objectName = inProgramName;

resolveQualifiedSystemPointer

(serviceProgramPointer : resolutionTemplate :
libraryPointer);
endif;



return serviceProgramPointer;

on-error *all;

return *null;

endmon;

/end-free

P getProgramAddress...

P E


Then, you obtain the system address of your program via the
getProgramAddress function:

D programAddress S * procptr

programAddress =
getProgramAddress
('PROGRAMA');

Next, setup your parameter argument:

D argVector S * dim(399) based(argVector__)
D argCount S 10U 0 inz

argCount = 3; // example

// set addresses of arguments
argVector(1) = %alloc(%size(arg1)); // example
argVector(2) = %alloc(%size(arg2));
argVector(3) = %alloc(%size(arg3));

Then, copy the memory to the arguments using MEMCPY:

D memcpy PR extproc('__memcpy')
D target * value
D source * value
D bytes 10U 0 value

memcpy // example
(argVector(1) :
%addr(arg1) :
%size(arg1));

Finally, make your call:

callProgram(programAddress : argVector__ : argCount);
dealloc(en) argVector__;

Have fun!!!

Kind regards,

Michael P. Scott
Programmer Analyst II | Merch-Setup Engineer Liaison

-----Original Message-----
From: rpg400-l-bounces@xxxxxxxxxxxx
[mailto:rpg400-l-bounces@xxxxxxxxxxxx] On Behalf Of Scott Klement
Sent: Wednesday, July 08, 2009 10:06 AM
To: RPG programming on the IBM i / System i
Subject: Re: Passing a pointer between programs when using a dynamic
call

Hi Stefan,

Is it possible to use a pointer as a parameter when calling another
program?
The program call has to be made up dynamically and executed using
qcmdexec or system API...

You have two questions here, I think. Is it possible to pass a pointer
as a parameter when calling a program? Yes! Provided that you are
doing a direct program-to-program call.

Is it possible to pass a pointer via QCMDEXC or system()? No.
Remember, QCMDEXC (and similar tools) receive one big character string
from your program, and they interpret the contents of that character
string, via scanning/parsing techniques. You can't pass any sort of
variable (including a pointer, which is after all, a variable) when
using those tools.


Program B gets invoked and need a mechanism to send back information
to program A.

Then you don't want to use QCMDEXC or it's friends.

Just to hide the complexity of the datastructure in program A my
thought was to create a service program ( program C ) with procedures
that can be called by program B. It then seems reasonably that a
pointer must be used to "connect" the procedures in pgm C with the
datastructure in pgm A. Along the run it might be needed for program C

to change pointers in pgm A datastructure ( realloc of memory ).

I don't really understand this part of your message at all.

1) Why does PROGRAM A work this way? Why do you need so much
flexibility in terms of the parameter list? Do you work for a software
house where your software has to be able to call a customer's program
with any arbitrary parameter list? I can't think of any other reason
someone would do something like this.

2) I don't understand the "Program C" business at all. If you're
passing the data via a parameter, how does a service program help? Why
not pass the data via the service program instead of the parameter list?

3) Why does a pointer need to be used to "connect" your programs?


Am I out on very thin ice here? Better solutions?


Hard to say. I think we need more information to even begin to give you
advice. Speaking for myself, at least, I really don't understand your
scenario.

--
This is the RPG programming on the IBM i / System i (RPG400-L) mailing
list To post a message email: RPG400-L@xxxxxxxxxxxx To subscribe,
unsubscribe, or change list options,
visit: http://lists.midrange.com/mailman/listinfo/rpg400-l
or email: RPG400-L-request@xxxxxxxxxxxx
Before posting, please take a moment to review the archives at
http://archive.midrange.com/rpg400-l.


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