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 / A silly ILE RPG question


Question:

Since there's no such thing as a comp.languages.rpgiv group I need to bother you people with a rookie question…

I'm calling C routines from ILE-RPG, using the PCALL instruction. Works great. To pass null-terminated strings I figured to throw in the %STR function, like

PCALL LOG(LOGLVL : %STR(LOGTXT))

but the compiler consistently flags %STR as an invalid token. (N.B. It works when I leave out the %STR() but then I have to modify my C routines to trim and terminate strings).

I did read the FM ;-) but can't find any restrictions on using %STR. Perhaps it's not allowed in a PCALL ? That would be a shame because it's the most obvious place to use it.

Any ideas most welcome. TIA


Books on this subject:
RPG IV Jump Start : Moving Ahead With the New RPG
Answer(s):



Is LOGTXT defined as a character field, or as a basing pointer?

It sounds like it's defined as a character field.

If so, try this (not properly aligned!)
D LogTxt             S      20A  Based(LogTxtPtr)
D LogTxtPtr          S        *
then use %Str(LogTxtPtr)

Hope this helps.
Gary Guthrie Editor, The RPG Source Technical Editor, NEWS/400 magazine




Another thing that might work, but wouldn't be as elegant as the pointer solution, would be to concatenate an X'00 (Hex 00 - Null) to the end of the string




On your prototype define your second parameter with the keyword Options(*String) and then use the built-in-function %TrimR to call your procedure like this:


CALLP LOG(LOGLVL : %TRIMR(LOGTXT))
Here's another example:
Dperror           PR            10I 0 ExtProc( 'perror' )
D                                 *   Value  Options( *String )

C                   Eval      RC       =  perror( %TrimR( FileNam ))





YES ! That works.
Hurray, I've written my 'hello world' program in RPG :
     D txt             S             40A   INZ('Hello, world !')

     D log             PR                  EXTPROC('logit')
     D    txt                          *   VALUE OPTIONS(*STRING)

     C                   CALLP     log(%TRIMR(txt))
     C                   RETURN
And the C module linked to this is simply
void logit (char *t)
{
  printf("'%s'\n", t);
}
Thanks for the solution.




Are you sure the RPG compiler you use has the same release level as the manual? There are many enhancements to RPGLE between OS/400 3.2 and 4.2. If your compiler is old many of the other suggestions I read so far will also fail to work. In that case, using %trimr() and appending a x'00' manually is your only solution.

Also, you cannot write your own str() function in rpg or C, unless you also pass the length of the character field, or know the length of the character field in advance. Since you want to find the last non-blank character, you have to start looking at the end of the character string, and the compiler has no way of finding out, unless you either pass fixed-length fields, or pass the length as a parameter.

It would be a great idea though, if the rpg compiler writers gave us a macro or template facility, so that we could write our own functions, which would look like procedure calls, but would be able to handle arbitrary parameter variable lengths, just like the built in functions. Right now prototyped functions cannot handle parameters of different storage size very well.






They can if they are character variables, but not numeric ones. You need to code the prototype with Options(*Varsize) which causes the compiler to pass "operational descriptors" along with the parameter.

The function then must do a call to CEEDOD to obtain the size of the expression or variable passed. This allows you to do implement this type of function even in V3R2 on CISC machines.

Unfortunately operational descriptors are not available for numeric variables so we don't have a good way of knowing length and decimal positions, which makes it hard to implement a %editc() look-alike.




Check out the new (V4R2) keyword VARYING available to variables & parameters in RPG/IV. Once the length is set (using %Len or %TrimR where appropriate), the program keeps track of it.

Passing procedure parameters this way you won't have to check the actual length, the program will know what storage to access (and what not to).




Me thinks this does it:
.
.
.
  *
  *    Determine input parameter lenght for procedure parameter.
  *
 C                   CALLP     CEEDOD(1         : DescType : DataType :
 C                                    DescInfo1 : DescInfo2: InLen    :
 C                                    *OMIT)
  *
 C     ' '           check     CenterString  LeftByte
  *
 C                   EVAL      WrkString =
 C                               %subst(CenterString:LeftByte:
 C                                      InLen - LeftByte + 1)
  *
 C                   EVAL      NbrofChar = %LEN(%trim(WrkString))
  *
 C                   IF        NbrofChar 









Found it now.... It's because I use TGTRLS(V3R2M0). Leave that out
and it works. Probbaly %STR was introduced after 3.2. Drat !
Thanks all for pointing me in the right direction syntactically.










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