| Use the MI to Work with Pointers in ILE RPG |
|
|
|
| Programming - RPG | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Written by Junlei Li | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Wednesday, 16 December 2009 01:00 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
If you've been avoiding this technique, maybe you shouldn't be.
With the introduction of the ILE programming model, high-level languages (HLLs), including RPG, are enabled to make bound calls (procedure calls). This makes it possible for programs written in ILE RPG to cooperate with all the other HLLs available on the i5/OS, including Java, and to reuse all existing algorithms and functionalities that have been implemented in other HLLs. This fact is often regarded as proof of the RPG language's openness and modernization.
At the same time, the i5/OS machine interface (MI) layer exposed invocation interfaces to ILE programs, which are referred to as "bound program access interfaces" in IBM's MI documentation and as "system built-ins" in IBM's ILE RPG documentation. Now, programs written in RPG as well as in other i5/OS HLLs can interact with the operating system at the lowest level, the MI layer. This enables RPG programs to reuse the most efficient algorithms provided by the MI layer and to access system objects (MI objects) directly. This makes the RPG programming language more powerful. Overview of MI PointersWe know that the i5/OS is an object-based operating system. As the well-known UNIX idiom says, everything in a UNIX system is a file; on i5/OS, everything is an object. And the only way we can refer to an i5/OS object (MI object) or data in the object is through the MI pointer. For example:
Also, MI pointers represent other objects in a program or in a process in run time, such as procedure pointers, instruction pointers, invocation pointers, and so on.
Then, how does one represent an MI pointer in an RPG program? Actually, the bound program access interfaces exposed to ILE HLLs by the MI layer do not distinguish different MI pointer types, and all 16-byte pointer types in ILE RPG and other ILE HLLs can be used in MI instruction invocations. Thus, all MI pointers can be represented by an RPG variable of pointer type (with data type field set to character '*' in position
Let's go through some of the most often used pointer operations. Pointer Operations Supported by ILE RPGAs an HLL supporting pointers, ILE RPG provides the following support for pointer operations:
Operating Pointers with MI InstructionsThe prerequisite to invoke an MI instruction is to declare the right prototype for it. It is quite time-consuming to declare and validate prototypes for all the more than 200 MI instructions that have bound program access interfaces. System-builtin Headers for ILE RPG, a sub-project of the open-source project i5/OS Programmer's Toolkit, is working on this task. Prototypes of MI instructions mentioned in the following examples are extracted from one of the header files of the project, SourceForge's mih52.rpgleinc.
Determining the Type of a Pointer
To make sure that a pointer is of an expected type, use MI instruction Compare Pointer Type (CMPPTRT). To find out the type of a pointer, use MI instruction Materialize Pointer (MATPTR).
The prototype of MI instruction CMPPTRT provided by mih52.rpgleinc is shown as the following:
In the following example ILE RPG program, CMPPTRT is used to test whether a given pointer is a system pointer.
This is the prototype of MI instruction MATPTR.
This example ILE RPG program uses MI instruction MATPTR to get the type of a pointer:
Retrieving Attributes of a Pointer
To retrieve attributes of a pointer, use MI instruction MATPTR. Here is an example of retrieving attributes of a procedure pointer (PROCPTR):
The following shows the procedure pointer information structure declared in mih52.rpglinc.
The following ILE RPG program T030 accepts a procedure pointer as its only input parameter and retrieves attributes of the given procedure pointer.
Another ILE RPG program, T029, calls program T030 twice, passing respectively a procedure pointer addressing procedure increase() in T029's program entry point (PEP) module and a procedure pointer addressing the C library routine printf().
You can see that procedure increase() is the first procedure of the first module of program T029, and the C library routine printf() is the fifth procedure of service program QC2IO's thirteenth module.
Managing i5/OS Objects by Using System Pointers
One can access an i5/OS object only by using a system pointer address to the object. A system pointer to an i5/OS object is somewhat like a ticket by which you are permitted to get on a train and find your seat. To invoke an object-related MI instruction on an i5/OS object, you must show such a ticket. Here are a couple of practical examples of accessing i5/OS objects by system pointers.
Exchange Data via a User Queue Object
A queue object (with object type code hex
Here is an example of exchanging data via a user queue object. First, we create a user queue object by calling API QUSCRTUQ. Next, we put a queue entry onto the created user queue object by using MI instruction ENQ. Last, we dequeue a queue entry from the user queue object by using MI instruction DEQ.
This CL command creates a user queue with name QPROC:
Here are the prototypes of MI instructions ENQ and DEQ:
ILE RPG program T025 enqueues an entry into user queue QPROC:
ILE RPG program T026 dequeues an entry from user queue QPROC:
Get All User Profiles of Your i5/OS Installation
Everything on i5/OS is an object. A user profile object (*USRPRF) is of object type hex 08 and sub-type code 01. Theoretically, we can retrieve all objects residing in a library (a context object in the MI layer) with the MI instruction Materialize Context (MATCTX). Here is an example of retrieving *USRPRF objects by MI instruction MATCTX.
This is the prototype of one of MATCTX's bound access interfaces, _MATCTX1:
ILE RPG program T031 lists all user profiles of an i5/OS installation:
ConclusionsWhen talking about using MI instructions in RPG programs, some of us might argue that it will affect code consistency and require extra training and maintenance. In my opinion, it is just a matter of viewpoint. For example, if you like to use routines in other i5/OS HLLs, such as C in memory operations or mathematical calculations, you should be aware that memory operation MI instructions and mathematical MI instructions provide the same functionality as their C library counterparts but without dependency on the C library's service programs, such as QC2UTIL2, and will then shorten the time required by an ILE RPG program's activation progress. Or if you consider RPG as the only native language on the platform, then you should also know that, starting with S/38, the platform has been speaking in the MI language to all of us.
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
View all articles by this author
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Last Updated on Monday, 14 December 2009 15:16 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| efnkay |
Use the MI to Work with Pointers in ILE RPG
Dec 16 2009 18:29:34 Wow...Nice post. I've dug into MI instruction coding on several occasions but hadn't ever really broken the ice with it. Getting to the point, you've expressed the finer points of using and exploiting pointers! (Sorry couldn't help myself.)
|
#153672 |
| junlei.li |
Dec 18 2009 07:30:56 Wow...Nice post. I've dug into MI instruction coding on several occasions but hadn't ever really broken the ice with it. Getting to the point, you've expressed the finer points of using and exploiting pointers! (Sorry couldn't help myself.)
Thank you, efnkay. Working with MI instructions is always an interesting experience. The instructions might reveal some underlying behaviors of the OS at the SLIC layer. But it is sad that there are not enough documentation and resources on MI instructions. And the limited documentation DOES contains errors. For example, there isn't a system builtin named _PROPB (Propagate bytes), the right name might be __memset. Thus, I'm grateful for peoples who have shared their MI knowledge with curious programmers like me. And I myself also want to share what I've learned and tested about MI instructions to others. Thank you again. |
#153673 |
| BVining |
Dec 23 2009 22:05:56 While I agree that some of the MI built-in names implied by the documentation is wrong (and have informed IBM of that), _PROPB isn't one of them. What makes you think _PROPB isn't available?
|
#153676 |
| junlei.li |
_PROPB doesn't work on V5R2
Dec 28 2009 02:57:53 While I agree that some of the MI built-in names implied by the documentation is wrong (and have informed IBM of that), _PROPB isn't one of them. What makes you think _PROPB isn't available?
Hi, Bruce. Thank you for your comment. I used to work on a V5R2 machine where _PROPB isn't available. I've tested the following 3 programs (2 in ILE RPG, 1 in ILE C) respectively under V5R2 and V5R4. The result is that built-in name __memset works on both V5R2 and V5R4, but built-in name _PROPB works only on V5R4. *) ILE RPG program bv1.rpgle @code /** * @file bv1.rpgle * * use built-in name '_PROPB'; * can be compiled and works fine on V5R4; * cannot get compiled under V5R2 with the following error: * @code * Definition not found for symbol '_PROPB'. * @endcode */ h dftactgrp(*no) d propb pr * extproc('_PROPB') d tgt_str * value d src_byte 1a value d count 10u 0 value d str s 16a inz(*all'abc') d /free propb(%addr(str) : x'F2' : 8); dsply 'result' '' str; *inlr = *on; /end-free @endcode *) ILE RPG program bv2.rpgle @code /** * @file bv2.rpgle * * use built-in name __memset; * * can get compiled either on V5R2 or on V5R4. */ h dftactgrp(*no) d propb pr * extproc('__memset') d tgt_str * value d src_byte 1a value d count 10u 0 value d str s 16a inz(*all'abc') d /free propb(%addr(str) : x'F2' : 8); dsply 'result' '' str; *inlr = *on; /end-free @endcode *) ILE C program bvc.c @code /** * @file bvc.c * * Can be compiled and works fine on V5R4. * When compiling bvc.c under V5R2, one will get the following error: @code Builtin function _PROPB is unrecognized. Definition not found for symbol '_PROPB'. @endcode */ # include # pragma linkage(_PROPB, builtin, nowiden) void *_PROPB(void *, int c, int n); int main() { char str = {"abcABCabcABCabcA"}; printf("%s\n", _PROPB(str, 0xF2, 8)); return 0; } @endcode Additionally, the reason why I thought that '__memset' might be the real built-in name of instruction PROPB is __memset's prototype declared in QSYSINC/H(STRING): @code #pragma linkage( __memset, builtin ) void *__memset ( void *, int, size_t ); @endcode which reveals the following facts: - first, __memset is a system builtin; - second, __memset has exactly the same prototype and functionality with what IBM documented instruction PROPB. Now, I still think that __memset MIGHT be the right built-in name of instruction PROPB at least on V5R2. Since it is not reasonable to provide two instructions/system built-ins with the same functionality. Thank you again and expect for your further advices! Junlei Li |
#153677 |




