Manejo Apuntadores en RPG
Manejo Apuntadores en RPG
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?
Program Storage
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
statement 51 had an error due to a pointer not being correctly set. The
* The pointer was set, but the object it referenced has been destroyed.
* 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.
DName+++++++++++ETDsFrom+++To/L+++IDc.Keywords++++++++++++++++++++
D pPointer S *
D BasedField S 20 Based(pPointer)
ComCon
Pointers at work
1. pPointer = *Null
1. pPointer = *Null
2. pPointer = An Address
3. pPointer = Another Address
5 4.
5.
pPointer
pPointer
=
=
Yet Another Address
%Addr(BlueField)
2
ComCon
Using pointers
Pointers have a data type of '*' and you don't define a length.
Actually uses 16 bytes of storage.
D BasedField S 5 Based(pPointer)
* "Overlays" Text1
D MyDS DS
D Text1 4 Inz('ABCD')
D Text2 4 Inz('WXYZ')
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 *
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.
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.
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
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 GetSpace PR ExtPgm('QUSPTRUS')
D SpaceName 20 Const
D pSpacePtr *
* Optional Parameter Group
D ErrorCode Const Options(*NOPASS)
D Like(StandardAPIError)
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 *
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.
D pGenProc S * ProcPtr
D GenProc PR 30 ExtProc(pGenProc)
pGenProc = %PAddr('Proc01');
Returned = GenProc();
pGenProc = %PAddr('AnotherProcAltogether');
Returned = GenProc();
ComCon
Any clearer now?
ISBN 1-58347-006-9
ComCon
Summary
Pointers open new possibilities.
Pointers can be dangerous.
Treat them with respect.