Getting Started With APIs From RPG
Getting Started With APIs From RPG
Getting Started With APIs From RPG
Presented by
Scott Klement
http://www.scottklement.com
2006-2010, Scott Klement
There are 10 types of people in the world. Those who understand binary, and those who dont.
Whats an API?
API = Application Programming Interface
An Interface
APIs represent a way for one application to interface with another one. For example, Order Entry software might need to interface with Shipping software to determine a shipping charge.
This presentation focuses on how to get started using the OS/400 API from an RPG IV (ILE RPG) program.
Well start by examining how IBMs documentation is laid out, and discuss how to find the API youre looking for, as well as which parameters it needs.
3
When you know the name of the API, but you dont know what it does (usually when youre trying to understand someone elses code) When you know what you want to do, but you dont know which API does the job.
IBM provides 3 ways of finding APIs: APIs by Category (When you dont know the API name.) API finder (When you do know the API name or title.) Alphabetical Listing of APIs (Ive never found a use for this.)
4
http://publib.boulder.ibm.com/iseries/
Programming APIs
For example...
Lets say youre reading a program, and you see code like the following:
CHGVAR VAR(%BIN(&RCVVARLEN)) VALUE(1000) CALL PGM(QDCRDEVD) PARM( &RCVVAR &RCVVARLEN 'DEVD0600' &DEV &ERRCODE + + + + )
In this case, you may not be sure what QDCRDEVD does, but you know its name. In that case, you want to be able to type the name and get information about the API. To do that, youll use the API Finder.
6
API Finder (1 of 2)
The API finder is for searching for an API. Its the Google for OS/400 API information. 7
API Finder (2 of 2)
Parameter Summary Area API Description, Locks & Authority Info Detailed Information about parameters Error Information
9
These arent required, but if you pass one, you have to pass them all. Same here,PLUS in order to pass group 2, you must also pass group 1.10
QMHSNDPM Example (1 of 2)
D QMHSNDPM D MsgID D MsgFile D MsgData D MsgDtaLen D MsgType D StackEntry D StackCount D MsgKey D ErrorCode D ErrorCode D BytesProv D BytesAvail D Msg D MsgKey /free Msg = 'This is a test. Don''t read this.'; QMHSNDPM( 'CPF9897': 'QCPFMSG *LIBL': Msg: : %len( %trimr(Msg) ) : '*DIAG': '*': 0: MsgKey: ErrorCode ); *INLR = *ON; /end-free 11 PR EXTPGM('QMHSNDPM') 7A const 20A const 32767A const options(*varsize) 10I 0 const Use CONST for Input 10A const parameters. 10A const 10I 0 const 4A BINARY(4) is always 32767A options(*varsize) 10I 0 in RPG IV. 10I 0 inz(0) 10I 0 inz(0) s s 200A 4A More about data types later.
ds
QMHSNDPM Example (2 of 2)
12
Data Types
The data types that are listed for each API are usually pretty self explanatory. Examples:
CHAR(20) = character field, 20 long (20A in RPG) PACKED(15,5) = packed, 15 digits w/5 decimal places (15P 5 in RPG) POINTER(SPP) = Pointer. (Data type * in RPG more info later!)
However, there are two data types that seem to cause a lot of confusion:
BINARY(4) = 4 byte binary integer. (10I 0 in RPG) BINARY(4), UNSIGNED = 4 byte unsigned binary integer (10U 0 in RPG) CHAR(*) = Character field with a special length, not VARYING (Declare this as a long character field with options(*VARSIZE) on the prototype.)
NOTE: In RPG, we declare our numeric fields by the number of digits we can store in them. So a 9P 0 field is 5 bytes long, but stores a 9 digit number. A 10I 0 field is a binary integer thats 4 bytes long, but stores a 10 digit number. NEVER USE THE B DATA TYPE, ITS NOT A TRUE BINARY INTEGER. THE I AND U DATA TYPES ARE, AND THEY RUN MUCH FASTER, TOO. 13
API Description
On the APIs page, after the Parameter Summary.
(This is the bottom of the box around the parm summary)
Info about what sort of authority users will need for their program to call this API. 14
There are detailed descriptions of all of the APIs parameters. This is what usually takes up most of the space on each APIs page.
15
Sometimes there are additional notes about why an error might be caused.
16
This structure is passed in a parameter to the API. Bytes Provided should tell the API how big the DS is. (That way, you can control the size of the Exception Data field!) You must set this before calling the API. Dont leave it blank! (x40404040 = 1,077,952,576) Bytes Available tells you how much error data the API sent back. You can leave off the fields on the end, as long as Bytes Provided is correct. You can set Bytes Provided to zero if youd like the API to send you an *ESCAPE message when it fails. NOTE: The CEE APIs, and the Unix-type APIs have separate mechanisms for error handling that I do not cover here. They are documented in the Information Center, however.
17
If you want to handle errors in your code, use this syntax instead. Nothing will go to the job log, its up to you to handle errors:
D ErrorCode ds D BytesProv 10I 0 inz(%size(ErrorCode)) D BytesAvail 10I 0 inz(0) D MsgId 7A D 1A D MsgData 1024A . . CALLP QMHSNDPM( other parms here : ErrorCode); if ( BytesAvail > 0 ); ErrMsg = MsgId + occurred called QMHSNDPM API!; // show ErrMsg to user! endif;
The use of %SIZE is a good idea. Let the compiler do the work, and help you when you need to make changes.
This way, if BytesAvail isnt zero after calling the API, you know theres an error.
18
DEVD0600
When an API can return different types of data, or can return it in many different formats (or would like to be able to do that at some point in the future!) it requests a format. Lets say youre writing an interactive program, and you want to know the IP address of your users PC. To find this out, youll need to retrieve information about the Display Device that hes using. This is done with the Retrieve Device Description (QDCRDEVD) API. This API returns all sorts of information about a device. There are hundreds of fields that it can return! It returns different information, depending on what sort of device youd like information about. A tape device (*TAP) has very different information than a display device (*DSP)! 19
The format name tells the API what the data structure looks like. The device name tells the API which device youre interested in.
21
22
ds
Note: The start position is one higher than the offset in the 23 manual.
Preceding data was variable-length. A list of repeating fields is returned. (such as a list of jobs on the system, list of objects in a library, etc.)
The best way to deal with variable offsets is with pointer logic. Never, ever hard-code an offset when an API passes it to you in a parameter!
24
25
Note that the length of that array entry is also variable. The offset from the previous slide tells us where the first library is. The second library will be immediately after the first. The Length of One Library Array Entry field tells us where the second one starts. (As well as the third, and fourth, and so on.)
26
Introduction to Pointers
The best way to handle variable offsets is with pointer logic. POINTER = A variable that stores an address in the systems main storage (or, memory). Just as a packed (or zoned) field is a variable designed to hold a decimal number, and a date field is designed to hold a date, and a time field is designed to hold a time, a pointer field is designed to hold an address in your systems memory.
Based Variables
Memory isnt automatically reserved to store their values. Instead, you control the place in memory where they reside. You can change it on the fly by changing the pointer.
27
21 20 19 18 17 16 15 14 13 12 11 10 M N a s h v i l l e
S t r
FF O
9 8
ET S
LY PO O -
a w b e r a r
Mr. Happy Pointer
29
30
D QUSRJOBI D RcvVar D RcvVarLen D Format D QualJob D InternalId D ErrorCode D Reset D MyData D OffsetUsrLibl D NumUsrLibl D EntryLen D LibEntry D LibName D Text D ASPNo D AspName
ds
ds
*...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+... LIBSCK Scott Klement, Testing Library LIBFGI Library for Finished Goods Inventory LIBSHP Library for most shipping programs LIBSAL Library containing all sales related progs LIBACC Library for Accounting Programs, Menus, Etc QGPL General Purpose Library QTEMP
Bottom F3=Exit
F12=Cancel
F19=Left
F20=Right
F24=More keys 33
User Spaces
USER SPACE = A disk object that acts very much like a memory allocation. Characteristics of a user space:
Created by calling an API. Can be marked auto-extend so that theyll automatically get bigger as needed. (With memory, you have to re-allocate to get a larger space.) You can get a pointer to a user space, and use it just as you would memory. You can base variables on a user space pointer, and use those variables like you would any other RPG variable. As a disk object, it can be saved in-between calls. Useful for remember last time I ran this values. It can be backed up to tape or optical media It can be shared with other jobs on the system. APIs exist for reading/writing user spaces for languages that dont support pointers. That includes OPM languages. APIs that need to return data that might be too large for an HLL variable will put their data in a user space. That way, its accessible from any OS/400 language.
34
List APIs
Many of the APIs that need to return a list of something (jobs, libraries, objects, modules, etc.) are called List APIs.
Characteristics:
Accept a user space library/name to store the results in. The generated user space always starts with a generic header Generic header contains offset, count and entry size information needed to read the list. The format of the list entries will vary depending on the API.
For example, you might want to get a list of the interactive jobs that are active on the system. So youd look for an API that does that.
APIs by Category Work Management (deals with how the system processes its workload) List Jobs (QUSLJOB) sounds good!
35
D QUSCRTUS D UserSpace D ExtAttrib D InitialSize D InitialVal D PublicAuth D Text D Replace D ErrorCode D QUSPTRUS D UserSpace D Pointer D QUSDLTUS D UserSpace D ErrorCode
ExtPgm('QUSCRTUS') 20A CONST 10A CONST 10I 0 CONST 1A CONST 10A CONST 50A CONST 10A CONST options(*nopass) 32767A options(*varsize:*nopass) 20A * ExtPgm('QUSPTRUS') CONST ExtPgm('QUSDLTUS') CONST options(*varsize)
PR
PR 20A 32767A
based(p_ListHeader) 10I 0 overlay(ListHeader:125) 10I 0 overlay(ListHeader:133) 10I 0 overlay(ListHeader:137) based(p_Entry) 10A 10A 6A 16A 10A 1A 1A
ds
s s
10I 0 10I 0
37
Create a User
*ALL'
List all active jobs to user space. Get a pointer to the user space. Calculate the offset to each entry, and point the ENTRY data structure at it.
offset = ListOffset + (x-1) * EntrySize; p_Entry = p_ListHeader + offset; if (Type = 'I'); except; endif; endfor;
If its an interactive job, print it out. Delete the user space and end the program.
38
Page/Line Columns
1/1 1 - 78
*...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+... QPADEV0001 BIZUJAME 239996 DSP01 KLEMSCOT 241320 ROGER KLEMROGE 242304 SYSCON QSECOFR 242331 DSP07 MARYZ 242326 S9S1 CHERYL 242223 39
More Information
Getting Started with APIs (Scott Klement: System iNetwork Programming Tips) http://systeminetwork.com/article/getting-started-apis Getting Started with APIs, Part 2 http://systeminetwork.com/article/club-tech-iseries-programming-tips-newsletter-49 Getting Started with APIs. Follow up to Part 2 http://systeminetwork.com/article/follow-getting-started-apis-part-2 Getting Started with APIs, Part 3 http://systeminetwork.com/article/getting-started-apis-part-3 Getting Started with APIs, Part 4 http://systeminetwork.com/article/getting-started-apis-part-4 APIs by Example (Carsten Flensburg, Gary Guthrie: System iNetwork Pgm Tips) (ongoing series) http://systeminetwork.com/archivesearch Working with APIs, Part 1 (Paul Morris: System iNEWS, Dec 2003) http://www.systeminetwork.com/article.cfm?id=17570 Working with APIs, Part 2 (Paul Morris: System iNEWS, Apr 2004) http://www.systeminetwork.com/article.cfm?id=18150 Fun with Pointers (Scott Klement: Personal Web site): http://www.scottklement.com/rpg/pointers.html IBM iSeries Information Center: http://publib.boulder.ibm.com/iseries/ 40
This Presentation
You can download a PDF copy of this presentation from: http://www.scottklement.com/presentations/
Thank you!
41