tnt400.com - AS/400 Tips And Techniques

Sponsored by news400.com

This page is a discussion on the mentioned topic.
Most of the answers are in their original posted form, including any technical/spelling/grammatical errors.
No guarantees are expressed or implied. :-)
Comments, corrections, concerns about this tip?

Got another AS/400 question? Ask it here


What's New?
See what's new at Tips-N-Tech.

AS/400 Tips-N-Tech
AS/400 tips, techniques, and FAQ. Updated frequently.
CODEPage/400
All the code samples you can eat! RPG, CL, DDS, etc. etc.
AS/400 FAQs
The official news400.com FAQs.






All AS/400 Tip Categories / AS/400 Programming / RPG IV help using APIs


Question:

Some background: New to AS/400 and RPG Have spent a few months looking at RPG III now want to start working in RPG IV, specifically with API calls and pointers. previous expirence with COBOL (on Honeywell DPS 6), C and Pascal (on PCs) Now then, I've been looking at the following APIs: List Database File Members (QUSLMBR) List Database Relations (QDBLDBR) both of which use a user space to return a list. I would like to use pointers to access this user spaces, as opposed to the Retrieve User Space (QUSRTVUS) API since pointer access is supposed to be faster. First off I was supprised that the source members in QSYSINC/QRPGLESRC for these APIs did not have prototypes for the API calls. Is there a reason for this? Second, it seems to me that the members in QSYSINC/QRPGLESRC can't really be included in your module. By that I mean that for the most part you would not use a /COPY QSYSINC/QRPGLESRC,mbrname in your source code. I base this on the fact that there are no prototypes in those members, and the fact that to use the data structures with a pointer to a user space you have to actually define the DS in your module with a BASED(ptrname) as shown in the example in "System API Programming" appendix B topic 3.2. I can find no way to use the pointer while leaving the DS in the include file. However, I did see this in the RPG manual(p 177):
   *
   * Define a basing pointer field and initialize to the address of the
   * data structure My_Struct.
   *
  D  My_Struct      DS
  D   My_array                    10    DIM(50)
  D
  D Ptr1            S             16*   INZ(%ADDR(My_Struct))

But I don't think that this really has the same effect as
  D  My_Struct      DS              BASED(Ptr1)
  D   My_array                    10    DIM(50)
  D
  D Ptr1            S             16*
Am I correct in this assumption? Help me out here folks, am I not understanding something here? Thanks in advance,


Answer(s):



Yup, you must be using p = %addr(arr(offset+1)) to do pointer advancing. This is ok, although handling an offset greater than 32766 leads to additional ugly coding usually involving a based multiple occurrence DS with the char(1) array in it. Brrr. What you can't do with an array but you can with pointer arithmetic is EVAL p = p - offset and even better, EVAL offset = ptr1 - ptr2.




I thought you could already do this in V3R2. I'm sure we're using it for APIs that access a user space. Or is it because we're actually advancing in an array....




Charles, you're right that the members in that file are not as useful as they could be. They were written in V3R1 before prototypes were supported in RPG IV. The problem with the data structures not being based is a holdover from the RPG III versions which couldn't declare based data structures. The RPG IV headers were supposed to be "the same" as the RPG III ones so customers could convert their programs to RPG IV without difficulty. But I agree that it's time to do something about them (note that I'm not speaking officially for IBM here). My guess is that we'd have to create a whole new source file to avoid disrupting current users of QRPGLESRC. For now, you can copy (not /COPY) in the data structure subfields into your own source, and unfortunately write the prototypes yourself. Sometimes it's helpful to look at the C prototypes in QSYSINC/H (although sometimes they're just confusing e.g. "void *"). P.S. not sure if anyone answered your question about pointer arithmetic, but yes, starting in V3R7 you can EVAL ptr = ptr + offset (zowie!). Thanks for reminding us about QSYSINC




Thanks for your reply. Have a couple of things... > From V3R1 to V3R6, you cannot calculate with pointers. You can have them set > with QUSRPTRUS and %ADDR and that's it. With V3R7, you can calculate with > them like > EVAL Pointer = Pointer + %size(structure). > > Before, you have to use some kind of workaround. That explains this little code snippet in IBM's example correct? C* and then incrementing LSTPTR to the Input Parameter Header C* C EVAL LSTPTR = %ADDR(ARR(QUSOIP + 1)) I wondered why they needed that array defined. In v3r7 can you say add the offset to a pointer with the following: C EVAL LSTPRT = LSTPRT + SizeOfEntry Thanks for you help.




you are completely right. Accessing user spaces with pointers is *much* faster than QUSRTVUS. The best thing about it, as you surely discovered, is the possibility of shifting a data area over the user space instead of retrieving them with a call. I saw programs that did then some MOVEing with the data. That has to be slower and it is. What we really miss with the /COPY is the possibility to change the source of the included /COPY member as we were able to with good old Auto Report. But there was only support for field names and attributes, and this can be done with ILE RPG, so i think that there's a little gap in programmer's support. At least is that my state of knowledge, i couldn't find anything about this feature on the handbook CD. Perhaps this is read by a IBMer/ress who solves the riddle or maybe this becomes a requirement? Back to the topic: When you code a DS that is "based", you have to get your pointer field filled. Before that, your DS is somewhere in nirvana. After that, you use a piece of storage that is accessable for you; that is a user space or variable storage of your program. A DS without "based" occupies the same place in the storage all the (run)time and cannot be shifted around. From V3R1 to V3R6, you cannot calculate with pointers. You can have them set with QUSRPTRUS and %ADDR and that's it. With V3R7, you can calculate with them like
EVAL Pointer = Pointer + %size(structure).
Before, you have to use some kind of workaround. You might be able to use this:
D Structure   DS      BASED(PtrStruct)
D Struct_F1             10
D Struct_F2             10
D Struct_Next            1
to move the structure, you use
EVAL PtrStruct = %ADDR(Struct_Next)
If you have to deal with offsets, what you have to when you use APIs, you might want to use an array.
D UserSpace  DS   BASED(PtrUsp)
D Offset               9B 0
D Array      1  32767  DIM(32767)
and use
EVAL PtrUsp = %ADDR(Array(Offset+1))

Has the disadvantage that you can only jump in 32K-steps in storage. But
that can easily be solved by a subroutine that does these jumps in a loop.

Hope this helps.










Other tips in this category:

Click here to see all categories.

Socket Programming And Timeout Issues
Deleting Duplicate Records From A Table
What are data queues and how to use
Retrieving SMTP Name
RPGLE example for Dynamic Screen Manager API
Calling APIs from CL - with examples!
Compare two strings in RPG character by character
How to search all pgms in QCLSRC for a keyword
Retrieve Database File Description (QDBRTVFD) API
How to redirect the output to STDERR from RPG-IV
Using Multiformat Logical To Join 2 Identical File
D-Spec *LIKE DEFN
RPG: Converting Character to Decimal
Example of ILE RPG CGI Program
Handling ILE RPG Numeric Overflow
Help with Subfile Programming in RPG III
Zoned parameter in ILE RPG
What's the best way to do modulus in CL?
RPG Nesting Source Print Utility
More on changing the SIGNON screen
A silly ILE RPG question
Calling Validation List API From ILE RPG
Soft Coding Module Names
RPG Multidimensional Arrays in Action
Build a Page-Equals-Size Lookup Window
Procedures within an ILE RPG program
Break msg from RPG
Source Debugger for batch jobs
RPGLE debugging
Timing out display sessions in DDS
Building Dynamic Stored Procedures
Put Message in System Log
Dynamic RPGSQL
Randomize function for the AS/400
What's the fastest way to do a simple RPG lookup?
First time Data queue application in RPG
Print file overflow in ILE RPG
Mapping Fields To Arrays in ILE RPG
Named inidicators
STRQMQRY: comparision operator '=' isn't correct?!
DSPDTAARA to an outfile - possible?
PCL ESC codes in RPG
Sharing DB files between two AS/400s
Help: AS/400 subfiles
How do you change the signon screen?
Determining Even/Odd Values in queries
Get day of the week in RPG
Convert UPPERCASE to lowercase
RPG IV help using APIs
Help with data area API
Detecing IFS Files from RPG
SQL in a CL program
Calling AS/400 APIs from ILE RPG
CVTDAT command to convert an *MDY to a *LONGJUL
CPYSPLF Automation
Subfile Window background problem
Using IFS APIs w/ ILE RPG
Packed or unpacked fields?
QRYDFN to source and back
What does the "optimize" parm do?
Determining the calling program
Sockets in RPG?
Sorting a user space
OVRDBF and SECURE() keyword in an ILE environment
RPG record locking
RPG Differences: V2R3 to V3R2 upgrade
Getting the relative record number (RRN)
What is the longest parameter usable in RPG?
A C function that returns a string to an RPG pgm
Problems with ZADD *ZEROS
Can you highlight code in SEU?
Reusing deleted records - OK?
Is there an easy way to change edit codes?
Help - Windowed Subfiles
Logical Files and DDS
AS/400 'machine language' - MI Programming
Library lists and performance
How to use ERRSFL
Updating in CL
Record lock wait time
Message subfile problem
Physical File Joins
CL: Copying User Profiles
Commands and PARM
ILE RPG, RPG IV, vs. RPG/400
RPG and subfiles
Multiple subfiles
Field masking for passwords
SFLMODE keyword in an ILE program
Subfile size
Color coding records in a subfile
MSGLINE in windows
Controlling cursor movement on a display file
API returns error! Why?
Put an RPG Program on the Web
Variable length records in RPG
Differences Between RPG400, RPG IV, and ILE RPG


You are at a news400.com site.
Contact Us | Report Bugs | Submit Comments/Suggestions | Read Site Use Agreement | Read Privacy Policy
Copyright © 2000 Duke Communications International.
This site is best viewed with the latest versions of Netscape or Internet Explorer, 800 x 600 resolution (or higher), and at least 256 colors.
Duke Communications   NEWS/400 | 29th Street Press | Business Finance | DominoPro | Selling AS/400 Solutions | SQL Server Magazine | Windows NT Magazine