The Cygnus Native Interface for C++/Java Integration

Writing native Java methods in natural C++

Cygnus Solutions


This documents CNI, the Cygnus Native Interface, which is is a convenient way to write Java native methods using C++. This is a more efficient, more convenient, but less portable alternative to the standard JNI (Java Native Interface).

Basic Concepts

In terms of languages features, Java is mostly a subset of C++. Java has a few important extensions, plus a powerful standard class library, but on the whole that does not change the basic similarity. Java is a hybrid object-oriented language, with a few native types, in addition to class types. It is class-based, where a class may have static as well as per-object fields, and static as well as instance methods. Non-static methods may be virtual, and may be overloaded. Overloading is resolved at compile time by matching the actual argument types against the parameter types. Virtual methods are implemented using indirect calls through a dispatch table (virtual function table). Objects are allocated on the heap, and initialized using a constructor method. Classes are organized in a package hierarchy.

All of the listed attributes are also true of C++, though C++ has extra features (for example in C++ objects may be allocated not just on the heap, but also statically or in a local stack frame). Because gcj uses the same compiler technology as g++ (the GNU C++ compiler), it is possible to make the intersection of the two languages use the same ABI (object representation and calling conventions). The key idea in CNI is that Java objects are C++ objects, and all Java classes are C++ classes (but not the other way around). So the most important task in integrating Java and C++ is to remove gratuitous incompatibilities.

You write CNI code as a regular C++ source file. (You do have to use a Java/CNI-aware C++ compiler, specifically a recent version of G++.)

You start with:

#include <gcj/cni.h>

You then include header files for the various Java classes you need to use:

#include <java/lang/Character.h>
#include <java/util/Date.h>
#include <java/lang/IndexOutOfBoundsException.h>

In general, CNI functions and macros start with the `Jv' prefix, for example the function `JvNewObjectArray'. This convention is used to avoid conflicts with other libraries. Internal functions in CNI start with the prefix `_Jv_'. You should not call these; if you find a need to, let us know and we will try to come up with an alternate solution. (This manual lists _Jv_AllocBytes as an example; CNI should instead provide a JvAllocBytes function.)

These header files are automatically generated by gcjh.