Calling MPE Intrinsics

Here is a tiny example how Java programs can call native code subroutines on the host platform using JNI, the Java Native Interface. The given example uses native method calls to invoke the MPE Intrinsics PRINTOP and PRINTOPREPLY to perform a simple dialog with the console operator. It can easily be adapted to call other user-supplied XL subroutines, of course.

The JNI is designed to work with native code written in the C or C++ languages. The parameter passing between the Java Virtual Machine and the native code subroutines makes heavy use of C preprocessor macros, pointers, nul-terminated strings and the like. So for interfacing to other programming languages it seems like a good idea to implement small wrappers in C that provide the "glue" between the non-C/C++ code and the JNI.

My example uses the free GNU gcc compiler to implement the JNI interface code. Calling MPE Intrinsics is somewhat tricky with GNU gcc as the compiler does not know anything about the SYSINTR file or the MPE Intrinsic mechanism. To the compiler it is just like any other external function call, so there is no special parameter checking or handling of optional or default parameters. This means that the programmer has to pay close attention to get the parameter passing right. To make this a little bit more complex, many MPE Intrinsics use 64bit "long pointers" (space id plus offset) instead of 32bit "short pointers" when passing parameters by reference. The HP C/iX (or c89) compiler has a special ^ symbol for long pointers, which is used in place of the * symbol. The GNU gcc compiler does not have this feature, so long pointers have to be "manually" constructed using small helper functions (using inline assembler instructions).

To avoid the above inconvenience, I created two variants of the example. One uses GNU gcc for the JNI interface but then calls the MPE Intrinsics via a small wrapper that is compiled by HP C/iX (c89), because the latter compiler provides convenient MPE Intrinsic handling via the #pragma intrinsic declaration. The other variant uses GNU gcc for the JNI interface but then calls the MPE Intrinsic via a small wrapper that is written in HP COBOL II/iX, which also handles Intrinsic calls much more conveniently. Both, the c89 as well as the COBOL wrapper routine do not use long pointers for interfacing the the GNU gcc code, which makes life much easier in this regard, too.

At present I have not coded a "pure gcc" or a "pure c89" example, but both should be possible. The former needs careful work to get the Intrinsic parameter passing right (including the long pointer handling). The latter needs a little tweak to the default JNI header files in /usr/local/java/jdk1.1.7/include and below, as HP C/iX does not handle the "long long" data type at present.

Lars Appel, 14-Aug-99