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