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 / Calling AS/400 APIs from ILE RPG


Question:

I am working on a project that requires the use of the Dynamic Screen Manager APIs, but try as I might there seems to be no way of declaring the call to match the parameter requirements of the API. The problem seems to be that all RPG calls, ILE or otherwise, whether you specify that the parameter is passed by reference, value or as a constant, the parameter passed is always the address of the data. Now in normal inter language calls this is OK. CL expects this and C is quite happy because all the parameters are just declared as being passed as pointers. Then you try and use the AS/400 APIs. I don't know if you have studied the APIs much, but the vast majority of parameter calls require that the parameter is passed by value, not by address. Until now have had no choice but to write a noddy little wrapper routine in C so I can cast the data types and call the API, but surely there must be a way of calling the API directory from ILE RPG. What was wrong with the API designers when they wrote AS/400, didn't they think RPG would be used for writing programs? If anyone has any idea at all how the hell you can call an API where the parameters need to be passed by value, please let me know. NOTE: The value keyword on procedure declarations does not actually pass the parameter by value, the procedure has code to copy the contents of the passed variable into the local variable at run time.


Answer(s):



The following little program in ILE RPG uses a few of the DSM API's. Browsing quickly through the API reference manual I couldn't see any DSM API's requiring value declarations.
     D f3              c                   x'33'
     D sa_norm         c                   x'20'

     D txt             s            128    inz('Press Enter to Roll, F3 to quit-
     D                                     .')
     D txtlen          s              9b 0 inz(32)
     D err             s              8    inz(x'0000000000000000')
     D aid             s              1
     D lines           s              9b 0 inz(1)
     D wf1             s              1
     D wrtn            s              9b 0

     D clrscr          pr             9b 0 extproc('QsnClrScr')
     D  mode                          1    options(*nopass) const
     D  cmdbuf                        9b 0 options(*nopass) const
     D  env                           9b 0 options(*nopass) const
     D  error                         8    options(*nopass)

     D wrtdta          pr             9b 0 extproc('QsnWrtDta')
     D  data                        128
     D  datalen                       9b 0
     D  fldid                         9b 0 options(*nopass) const
     D  row                           9b 0 options(*nopass) const
     D  col                           9b 0 options(*nopass) const
     D  strmatr                       1    options(*nopass) const
     D  endmatr                       1    options(*nopass) const
     D  strcatr                       1    options(*nopass) const
     D  endcatr                       1    options(*nopass) const
     D  cmdbuf                        9b 0 options(*nopass) const
     D  env                           9b 0 options(*nopass) const
     D  error                         8    options(*nopass)

     D getaid          pr             1    extproc('QsnGetAID')
     D  aid                           1    options(*nopass)
     D  env                           9b 0 options(*nopass) const
     D  error                         8    options(*nopass)

     D rollup          pr             9b 0 extproc('QsnRollUp')
     D  lines                         9b 0                  const
     D  top                           9b 0                  const
     D  bottom                        9b 0                  const
     D  cmdbuf                        9b 0 options(*nopass) const
     D  env                           9b 0 options(*nopass) const
     D  error                         8    options(*nopass)

     C                   eval      wrtn = clrscr('0' : 0 : 0 : err)
     C                   dow       wrtn = 0
     C                   eval      wrtn = wrtdta (txt : txtlen : 0 : 23 : 2 :
     C                             sa_norm : sa_norm : sa_norm : sa_norm :
     C                             0 : 0 : err)
     C                   eval      wf1 = getaid (aid : 0 : err)
     C                   if        aid = f3
     C                   leave
     C                   endif
     C                   eval      wrtn = rollup (lines : 1 : 24 : 0 : 0 : err)
     C                   enddo

     C                   eval      *inlr = *on
Remember to bind this to serviceprogram QSNAPI




You're clearly bringing up an interesting issue. Not being a C expert, I can't say much one way or another except that I've used numerous APIs with no noticeable problem. I've yet to run into an API that I can't call successfuly in ILE RPG in fact. (Unfortunately, I have yet to get into DSM.) The IFS APIs in 'OS/400 UNIX-Type APIs' are examples where prototyping for the VALUE keyword seems to work just fine. By just looking at the documentation, I don't see any significant difference between the ways the DSM APIs and the IFS APIs are defined. So, my first question is: How can you tell by looking at the documentation that the DSM APIs will react to parameter definitions differently than the IFS APIs, for example? Are IFS APIs *not* expecting parameters to be passed 'by value'?




Unless a program (including an API) is expecting to receive a parameter passed by value, this will not work. C library functions receive parameters by value. However, most other APIs receive parameters by reference. Maybe you're referring to passing by read-only reference (i. e., specifying the Const keyword in an RPG IV prototype). Mike Cravitz NEWS/400 Technical Editor




I have created ILE RPG prototypes for the APIs that I use. When you create the prototype you can specify that the parameter is passed by value, then just use the CALLP opcode. Works quite well.




I will give you an example. The Dynamic Screen Manager APIs tend to have their parameter lists set up to pass by value rather than by reference. Here (off the top of my head) is one specific example. The API QsnCrtCmdBuf is passed 5 parameters as follows,
p1    Initial buffer size    int   or   10I in rpg
p2    increment size       int    ditto
p3    max size               int    ditto
p4    address of buffer handle    long *
p5    error data structure            char *
this differs say from the dataqueue send APIs which expect all of their parameters to be pointers. The above API, because pointers are 16 bytes long on the AS/400, decides to pass the variable contents instead, presumably for performance reasons. Now If you read the AS/400 ILE RPG manuals carefully you spot a pattern. The PARM statement explicitly states that parameters are passed by reference. Hence you can never receive a parameter into a data structure because it is already allocated in storage elsewhere. Using procedure calls you may be forgiven for thinking that parameters are passed differently, but this is not the case. Parameters can be passed by reference, value and as const. Pass by reference is exactly the same as using parm, and the parameters must match exact size ad type for obvious reasons. Pass by value allows you to use different field sizes and types. This is because the parameter is copied into the storage of the procedure. Pass as const is an interesting one. It is supposed to represent a read only variable, but if you read the manuals carefully you see that you have to make sure the procedure does not change the variable. Why? well obviously because it is really being passed by reference, and changing it would change the original storage, even if it is a constant !! So this leaves me believing that it is not possible to call a lot of the system APIs, because as I said earlier some of them expect the variable contents to be passed on the stack (if the AS/400 has a concept of a stack) instead of the reference to the variable. Another give-away is the fact that functions like QsnCrtCmdBuf returns a result field as well, and there is no support for this in RPG without procedures. Have you written much in C ? If you have then the above can be explained more simply by showing that variables are always passed by address e.g..
callproc(&parm1, &parm2, &parm3);
.
.
.
callproc(int *parm1, char *parm2, packed(7,2) *parm3)
{
.
.
If you have any examples of code you have written to such APIs as these, I would love to see how you coded them.




I guess I don't quiet understand your problem. I have used MANY system APIs with RPG with no problem whatsoever. Do you have any examples?





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