Java Reference
In-Depth Information
naming scheme is followed for all native methods. For a deep package structure,
the native function name can grow quite long.
This process of creating a long C-side function name from the Java-side pack-
age, class, and method name is referred to as name mangling and is used to avoid
namespace collisions. The generated long names are called mangled names. If
one uses overloaded native method declarations, then the mangled native names
are longer still, with the overloaded names augmented by a mangled argument
signature to distinguish the multiple overloaded function names. Again, the rules
for determining the mangled function names are straightforward, but it is easiest
to just compile the Java class and run javah to generate the header file contain-
ing the exact mangled function names needed, especially since the header file is
always required anyway.
Even though our native method declarations declared no parameters, the imple-
mentation functions actually receive two arguments. This pattern is true of all
native methods. There are always two “extra” arguments in the native implementa-
tion function followed by the actual parameters declared in the Java class file.
The first argument is always a JNIEnv pointer, and the second argument
is always either a jclass type for static methods or a jobject type for
instance (non-static) methods. The JNIEnv pointer is very important to JNI. (For
those unfamiliar with C/C
, the presence of the * following the JNIEnv
type indicates that it is a pointer.) It is through the JNIEnv data type that native
code implementations gain access to Java objects. We explain how this works in
more detail later.
The data types seen above - JNIEnv , jobject , and jclass - along with
several others, are defined in the jni.h file that is included at the top of the
generated header file. The jni.h file can be found in the Java 2 SDK installation
directory in the include subdirectory. Examining the jni.h file can be daunting,
but if you choose to examine it, you will see that it contains different definitions
for C and C
++
.
In addition to definitions of the jobject and jclass data types, there are
also definitions of various other j data types that represent C or C
++
. Therefore the same jni.h file can be used for both C and C
++
versions
of Java data types - for example, jint for Java's int , jfloat for Java's float ,
and jstring for String . There is a mapping from each Java primitive type
and a few important Java objects (like String , Class , and Throwable )to
corresponding j data types in C or C
++
. These j types are needed on the
C-side to ensure a match between primitive types. For example, a Java float is
always 32 bits, but a C float could be 32 or 64 bits, depending on the underlying
platform. Therefore it is unsafe to map a Java float directly to a C float ,but
a C-side jfloat is guaranteed to always be 32 bits in length, just like a Java
float . Similarly, a jint is always 32 bits long, never 64. Because C doesn't have
a primitive Boolean type, Java boolean types are mapped to jboolean types
in jni.h , along with the constants JNI - TRUE and JNI - FALSE .Wediscuss
these data type mappings later, but for this example, we won't need any of the
mappings. In fact we won't even need the jobject and jclass data types.
++
Search WWH ::




Custom Search