0% found this document useful (0 votes)
56 views41 pages

Manejo Apuntadores en RPG

RPG IV pointers allow fields to be dynamically positioned in memory based on the value of a pointer field. Pointers must be carefully used to avoid errors, as they can access any memory location. Triggers can use pointers to map externally described files directly onto portions of the trigger buffer, rather than copying data. This avoids unnecessary data movement and allows accessing before and after images efficiently.

Uploaded by

Luis Cardenas
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
56 views41 pages

Manejo Apuntadores en RPG

RPG IV pointers allow fields to be dynamically positioned in memory based on the value of a pointer field. Pointers must be carefully used to avoid errors, as they can access any memory location. Triggers can use pointers to map externally described files directly onto portions of the trigger buffer, rather than copying data. This avoids unnecessary data movement and allows accessing before and after images efficiently.

Uploaded by

Luis Cardenas
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 41

ComCon

Coming to Grips with


Pointers and User
Spaces in RPG IV

ComCon
5, Oakton Court
Ballybrack Phone: +353 1 282 6230
Co. Dublin
Ireland
e-Mail: tuohyp@comconadvisor.com
Web: www.ComConAdvisor.com
Paul Tuohy
ComCon
Agenda
What are pointers?
How to use pointers.
Why use pointers?
Allocating record layouts in trigger programs
Used with C functions
Dynamic memory allocation
User spaces
Procedure pointers
ComCon
What is a pointer?

Basing pointers are used to locate the


storage for based variables. The storage is
accessed by defining a field, array, or data
structure as based on a particular basing
pointer variable and setting the basing
pointer variable to point to the required
storage location.

From: WebSphere(R) Development Studio ILE RPG Reference - Basing


Pointer Data Type
ComCon
What is a pointer?
A pointer is a field that contains a memory address.
Assuming that Name is a 30-character field, translate the eval operation
as "from the address of Name, blank out the next thirty characters".
If we could control "the address of Name", we would have a pointer!

Program Storage

Eval Name = *Blanks


ComCon
Pointers have always been used in . . .
Pointers are not new to RPG -- we just have not been able to
manipulate them.
Multiple Occurrence Data Structures
The occurrence of the database is based on an offset of the address of
the data structure.
– DS = Address of MODS + (Length of DS * (Occurrence – 1))
Parameter Lists
When passing a parameter the actual parameter field is not passed, but
a pointer containing the address of the parameter field. This address is
then used as the basis for the parameter field in the called program.
Lets take a closer look at parameters!
ComCon
Parameter lists

I
J
K
Storage of Called Program
Storage of Calling
Program

X Y Z

BProgram(I: J: K);
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
D BProgram PI
D X 15
D Y 10
D Z 5
ComCon
The problem with pointers

I
J
K
Storage of Called Program
Storage of Calling
Program

X Y Z
BProgram(I: J: K);
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

D BProgram PI
D X 15
D Y 10
D Z 15
Oops!
Z = *Blanks;
ComCon
The problem with pointers

I
J
K
Storage of Called Program
Storage of Calling
Program

X Y Z
BProgram(I: J: K);
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

D BProgram PI
D X 15
D Y 10
D Z 15
Oops!
Z = *Blanks;
ComCon
Better get used to . . .
Message ID . . . . . . : RNQ0222

Date sent . . . . . . : 13/09/02 Time sent . . . . . . : 11:40:31

Message . . . . : Pointer or parameter error (C G D F).

Cause . . . . . : RPG procedure BASICF in program SPACE01/BASICF at

statement 51 had an error due to a pointer not being correctly set. The

cause of the error is most likely one of the following:

* A basing pointer was not set.

* A procedure pointer was not set.

* The pointer was set, but the object it referenced has been destroyed.

* A parameter was not passed to the program containing the procedure.

* A parameter was not passed to the procedure by its caller within the program.

* A pointer offset was greater than the size of the space the pointer was pointing to.
ComCon
Remember
When you are using pointers . . .
You are indiscriminately playing with memory.

You must be careful.


ComCon
Pointers in RPG IV
We can now define pointer data types.
Also, we can define fields, arrays and data structures whose
"positioning" in memory is based on the value of a pointer.
In other words, when a field is based on a pointer, memory is not
allocated for the field when the program loads but is allocated dynamically
based on the value of the pointer field.

If a pointer is used but not defined, the compiler will


automatically define it – so watch out for spelling!

DName+++++++++++ETDsFrom+++To/L+++IDc.Keywords++++++++++++++++++++
D pPointer S *

D BasedField S 20 Based(pPointer)
ComCon
Pointers at work

1. pPointer = *Null

Storage of Program 1 BasedField


ComCon
Pointers at work

1. pPointer = *Null
2. pPointer = An Address
3. pPointer = Another Address
5 4.
5.
pPointer
pPointer
=
=
Yet Another Address
%Addr(BlueField)

Storage of Program 1 BasedField

2
ComCon
Using pointers
Pointers have a data type of '*' and you don't define a length.
Actually uses 16 bytes of storage.

Fields are "subject" to a pointer using the Based Keyword.


The value of a pointer is set using the %Addr Built-in
Function.
DName+++++++++++ETDsFrom+++To/L+++IDc.Keywords++++++++++++++++++++
D pPointer S * Inz(%Addr(Text1))

D BasedField S 5 Based(pPointer)
* "Overlays" Text1

D MyDS DS
D Text1 4 Inz('ABCD')
D Text2 4 Inz('WXYZ')

C Eval pPointer = %Addr(Text2)


* Now, BasedField "Overlays" Text2
ComCon
Why use pointers?
* When allocating record layouts in trigger programs.
* Used with C functions.
* Dynamic memory allocation.
* Used with many APIs - e.g., user spaces
* As a way of calling procedures.
ComCon
Standard trigger buffer
D TriggerBuffer DS Qualified
D FileName 10
D LibraryName 10
D MemberName 10
D Event 1
D Time 1
D CommitLock 1
D Fill01 3
D CCSID 10I 0
D RRN 10I 0
D Fill02 4
D OldOffset 10I 0 Offset to Original
D OldLength 10I 0 Record
D OldNullOff 10I 0
D OldNullLen 10I 0
D NewOffset 10I 0 Offset to New
D NewLength 10I 0 Record
D NewNullOff 10I 0
D NewNullLen 10I 0
* Before and After Images
ComCon
Accessing the Trigger Buffer
The %SUBST Built-in Function can be used to copy the
contents of the Trigger Buffer to the relevent externally
described data structures.

D OldFile E DS ExtName(FileName)
D Qualified
D NewFile E DS ExtName(FileName)

OldFile = %SubST(TriggerBuffer:
TriggerBuffer.OldOffset+1:
TriggerBuffer.OldLength);
NewFile = %SubST(TriggerBuffer:
TriggerBuffer.NewOffset+1:
TriggerBuffer.NewLength)
ComCon
Using pointers
The two externally described data structures can be mapped
onto the relevent portions of the Trigger Buffer by basing
them on pointers and setting the values of the pointers to be
the address of the buffer + the relevent offset.
No data is copied!!!

D OldFile E DS ExtName(FileName)
D Qualified
D Based(OldPtr)
D NewFile E DS ExtName(FileName)
D Based(NewPtr)

D OldPtr S *
D NewPtr S *

OldPtr = %Addr(TriggerBuffer) + TriggerBuffer.OldOffset


NewPtr = %Addr(TriggerBuffer) + TriggerBuffer.NewOffset
ComCon
C functions
Many C functions require pointers as parameters and return a
pointer.
Example: The strtok (string tokenize) function.
This function breaks up a string into "tokens“
Refer to the Redbook "Who Knew You Could Do That With RPG IV?"
for detailed details.
C functions are not easy to interpret.
• Function names are case sensitive.
• Refer to Barbara Morris’ "Converting from C prototypes to RPG
prototypes"
http://www.opensource400.org/callc.html.

D GetToken Pr * ExtProc('strtok')
D pString * Value Options(*String)
D pDelimiters * Value Options(*String)
ComCon
Other C functions
qsort and bsearch can be used as more powerful versions of
SORTA and LOOKUP.
Refer to the Redbook "Who Knew You Could Do That With RPG IV?"
for details and examples.

D SortIt PR ExtProc('qsort')
D DataStart * Value
D Elements 10U 0 Value
D Size 10U 0 Value
D CompFunc * ProcPtr Value

D FindIt PR * ExtProc('bsearch')
D LookFor * Value
D DataStart * Value
D Elements 10U 0 Value
D Size 10U 0 Value
D CompFunc * ProcPtr Value
ComCon
Dynamic Memory Allocation
Dynamic Memory Allocation is useful if you are unsure how
much space will be required by a variable at run time.
%Alloc - allocates the required amount of storage.
%ReAlloc - reallocates the current storage to a new size
DeAlloc - frees the allocated storage
–N.B. Allocated storage should be freed.

D Array S 10 Based(pArray) Dim(10000)


D pArray S *
D MaxElem S 10U 0 Inz(10)
/Free
pArray = %Alloc(%Size(Array) * MaxElem);
MaxElem = MaxElem + 10;
pArray = %ReAlloc(pArray: %Size(Array) * MaxElem);
DeAlloc pArray;
*InLR = *On;
/End-Free
ComCon
Example of Dynamic Memory Allocation
This example shows the use of dynamic memory allocation for
an array that may have more then 32767 elements.
The array is “repositioned” every 32767 elements.
D PathArray S * Dim(32767)
D Based(pPathArray)
// Allocate memory for the array of pointers
pPathArray = %alloc((%size(pDataPtr) * NumberInList));

// Build the array of pointers to the path entries


for i = 1 to NumberInList;
j = j + 1;
If (j > %Elem(PathArray));
pPathArray = pPathArray +
(%Size(pDataPtr) * %Elem(PathArray));
j = 1;
EndIf;
PathArray(j) = pDataPtr;
ComCon
Example of Dynamic Memory Allocation
1. NumberInList = 70,000 PathArray
%Size(PDataPtr) = 16
2. pPathArray= %alloc((%size(pDataPtr)*NumberInList));
%Alloc assigns 1,120,000 bytes
< 1 ----------------------------------------------------- 1,120,000 >

2. PathArray 4. PathArray 5. PathArray


< 1 ---------------- 524,272 >< 524,273------------ 1,048,544 >< 1,048,545 --------- 1,572,816 >

pPathArray = address of allocated memory


3. Program loops through 32767 elements of PathArray
4. “Move” the position of the array
pPathArray = pPathArray +
(%Size(pDataPtr) * %Elem(PathArray));
5. etc.
ComCon
What is a user space?
Contrary to popular belief, a user space is not what you find
between a user's ears.

It is
An object on the iSeries (I5, AS/400) with an object type of *USRSPC.
It is simply a stream of bytes that you can access directly from within a
program.
A user space effectively becomes a field in your program.
More precisely (even though it might sound extremely vague), a user
space is whatever you want it to be.

The advantages to employing a user space lie in speed of


access and the fact that data can be shared between
programs without having to perform I/O!!!!
ComCon
User space APIs
You must use APIs to create user spaces and manipulate their
contents.
In fact, the only user space command you will find is the Delete User
Space (DLTUSRSPC) command.

Incorporating a user space into an application involves two


user space APIs:
Create User Space (QUSCRTUS).
Retrieve Pointer to User Space (QUSPTRUS).
ComCon
Create user space
The QUSCRTUS API is called to create a user space

D CreateSpace PR ExtPgm('QUSCRTUS')
D UserSpaceName 20 Const
D Attribute 10 Const
D Size 10I 0 Const
D Initial 1 Const
D Authority 10 Const
D Text 50 Const

* Optional Parameter Group 1


D Replace 10 Const Options(*NOPASS)
D ErrorCode Const Options(*NOPASS)
D Like(StandardAPIError)
* Optional Parameter Group 2
D Domain 10 Const Options(*NOPASS)
* Optional Parameter Group 3
D TransferSize 10I 0 Const Options(*NOPASS)
D OptimumAlign 1 Const Options(*NOPASS)

CreateSpace(UserSpace:'DTA':10000: X'00':'*ALL':Text);
ComCon
Create user space
The parameters used on the QUSCRTUS API are:
UserSpace: The name and library of the user space.
Attribute: The attribute parameter is any name you wish it to be.
Size: The initial length of the user space in bytes.
Initial: The initial value used to fill the user space.
Authority: Public authority to the user space.
Text: The text description.

DName+++++++++++ETDsFrom+++To/L+++IDc.Keywords++++++++++++++++++++
D UserSpace S 20 Inz('USERSPACE *CURLIB')
D Attribute S 10 Inz('DTA')
D Size S 10I 0 Inz(10000)
D Initial S 1 Inz(X'00')
D Authority S 10 Inz('*ALL')
D Text S 50 Inz('Sample User Space')
ComCon
Fill user space
We map a variable in the program onto the user space.
 If we change the variable, we are also changing the user space.
 We map the CATSPACE array onto the CATEGORY user space.
 Each element of CATSPACE will contain a record from the Category
file.

D CatData E DS ExtName(Category)

D NumRows S 5I 0 Based(pNumRows)
D pNumRows S *

D CatSpace S Dim(32767) Based(pCatSpace)


D Like(CatData)
D pCatSpace S *
ComCon
Fill user space
The call to QUSPTRUS API returns a value in the pNumRows
field.
 This value reflects the address of the requested user space.
 NumRows now overlays the first two bytes of the user space.
 pCatSpace is equal to the value of pNumRows + 2.
 The array CatSpace overlays the user space starting at position 3.

D GetSpace PR ExtPgm('QUSPTRUS')
D SpaceName 20 Const
D pSpacePtr *
* Optional Parameter Group
D ErrorCode Const Options(*NOPASS)
D Like(StandardAPIError)

D UserSpace S 20 Inz('CATEGORY *LIBL ')

GetSpace(SpaceName:pNumRows);
pCatSpace = pNumRows + %Size(NumRows);
ComCon
Fill user space
We have a loop that fills the user space by reading a record
from the category file and adding it to the next element of the
array.

NumRows = 0;

Read Category;
DoW Not %EOF(Category);
NumRows = NumRows + 1;
CatSpace(NumRows) = CatData;
Read Category;
EndDo;
ComCon
Using the user space
This example shows a subfile being loaded from a user space
instead of a file.
 The program DOES NOT contain a F spec for the file.
 Again, we define the array based on a pointer.

D CatData E DS ExtName(Category)

D NumRows S 5I 0 Based(pNumRows)
D pNumRows S *

D CatSpace S Dim(32767) Based(pCatSpace)


D Like(CatData)
D pCatSpace S *
ComCon
Using the user space
The call to the QUSPTRUS API maps the array to the user
space.
The call to QUSPTRUS is usually issued in the *INZSR subroutine,
since it needs to be done only when the program is first loaded.

// Obtain pointers to the user space

GetSpace(SpaceName:pNumRows);
pCatSpace = pNumRows + %Size(NumRows);
ComCon
Using the user space
The subfile is now loaded from the array as opposed to the
category file.
 The relative record number (RRN) for the subfile doubles as the
element pointer for the array.
 Each iteration of the For loop places the next element of the array in the
next subfile record.
- The same field names are used in the subfile record format and the
CatData data structure.

For RRN = 1 To NumRows;


CatData = CatSpace(RRN);
Write SubRec;
EndFor;
ComCon
APIs and user spaces
User spaces are used with many of the system-supplied APIs,
especially any of the "list style" APIs.
Data is "output" to a user space and your program pages through the
user space.

This is an example of using the List Objects API


D ListObjects PR ExtPgm('QUSLOBJ')
D UserSpace 20 Const
D Format 8 Const
D Objects 20 Const
D ObjectType 10 Const
D ErrorCode Like(StandardAPIError)

CreateSpace('MYSPACE QTEMP ':'DTA':10000: X'00':'*ALL':


'All Objects in MYLIB');
ListObjects('MYSPACE QTEMP ':'OBJL0100':
'*ALL MYLIB ':'*ALL ':APIError);
ComCon
API documentation
The user space APIs are documented in the Information
Center under Programming->APIs->APIs by Category->Object
APIs.

The use of user spaces for other APIs is detailed in the


documentation of the individual APIs (like QUSLOBJ)
ComCon
Categories of APIs
Each has its own section, so pick a topic and while away a
weekend in perusal.
Backup and Recovery APIs Office APIs
Client Management Support APIs Operational Assistant APIs
Communications APIs Performance Collector APIs
Configuration APIs Print APIs
Debugger APIs Problem Management APIs
Dynamic Screen Manager APIs Program and CL Command APIs
Edit Function APIs Registration Facility APIs
File APIs Remote Procedure Call APIs
Hardware Resource APIs Security APIs
Hierarchical File System APIs Server Support APIs
High-Level Language APIs Software Product APIs
ILE CEE APIs UNIX-Type APIs
Journal and Commit APIs User Interface APIs
Message Handling APIs Virtual Terminal APIs
National Language Support APIs Work Management APIs
Network Management APIs Work Station Support APIs
Object APIs Miscellaneous APIs
ComCon
Procedure pointers
Procedure pointers point to the address of a procedure
Identified by the ProcPtr Keyword
The ExtProc keyword has the name of the pointer
Value set using the %PAddr BIF.
–Watch those quotes!
–Watch case!
–Parameters should be the same for all procedures. No check; it is up to you.

D pGenProc S * ProcPtr
D GenProc PR 30 ExtProc(pGenProc)

pGenProc = %PAddr('Proc01');
Returned = GenProc();
pGenProc = %PAddr('AnotherProcAltogether');
Returned = GenProc();
ComCon
Any clearer now?

Basing pointers are used to locate the


storage for based variables. The storage is
accessed by defining a field, array, or data
structure as based on a particular basing
pointer variable and setting the basing
pointer variable to point to the required
storage location.

From: WebSphere(R) Development Studio ILE RPG Reference - Basing


Pointer Data Type
ComCon
Check out the RPG IV Redbook
Available now - SG24-5402
 Go to www.redbooks.ibm.com
–You can read it online, download
the PDF file, or order a hardcopy Who Knew You Could Do That with
Includes worked examples of RPG IV?
A Sorcerer's Guide to System Access and More
– TCP/IP sockets
– CGI programming
– Using the C function library
– ILE error handling
– and much more SG24-
5402

International Technical Support Organization


Rochester, Minnesota
ComCon
Or check out
Available at
www.mcpressonline.com
www.midrange.com
www.amazon.com

ISBN 1-58347-006-9
ComCon
Summary
Pointers open new possibilities.
Pointers can be dangerous.
Treat them with respect.

They are a neccessity for many C functions.


They are a neccessity for many APIs.
User spaces are great!

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy