Contents Previous Next

Chapter   4

KNI Data Types


This chapter specifies the native data types supported by KNI. The data types are defined in the kni.h header file.

4.1 Primitive and Reference Types

KNI defines a set of C/C++ types that correspond to the primitive and reference types in the Java programming language. These primitive and reference types are used for referring to data structures inside KNI functions.

In addition, KNI defines special return types that must be used for specifying the return type of each native function that uses the KNI API.

To ensure maximum portability of native code, you shall not use any VM-specific data types in your native code that uses the KNI API.

4.1.1 Primitive Types

TABLE 2 describes the primitive types in the Java programming language and the corresponding types in the KNI. Just like their counterparts in the Java programming language, all the primitive types in the KNI have well-defined sizes.

TABLE 2  –  The KNI primitive types
Java language type
KNI primitive type
Description
boolean
jboolean
unsigned 8 bits
byte
jbyte
signed 8 bits
char
jchar
unsigned 16 bits
short
jshort
signed 16 bits
int
jint
signed 32 bits
long
jlong
signed 64 bits
float
jfloat
32 bits
double
jdouble
64 bits

The jsize integer type is used to describe cardinal indices and sizes; this is accomplished via the C/C++ typedef mechanism:

 
    typedef jint jsize; 

4.1.2 Reference Types

KNI includes a number of reference types that correspond to the different kinds of reference types in the Java programming language. The KNI reference types are organized in the type hierarchy shown below.

Graph showing hierarchy of KNI reference types.

FIGURE 1  –  KNI reference types

When used in conjunction with The C Programming Language, all other KNI reference types are defined to be the same as type jobject by the use of the C typedef mechanism. For example:

    typedef struct _jobject* jobject; 
    typedef jobject jclass; 

Note that jobject is intended to be an opaque type. That is, the KNI programmer may not rely on the internal structure of this type, as its definition may vary from one virtual machine implementation to another.

4.1.3 Return Types

KNI defines special return types that must be used when defining the return type for each native function that uses the KNI. The following return types are supported.

TABLE 3  –  Native function return types
Java language type
KNI type
Corresponding KNI return type
void
<n/a>
KNI_RETURNTYPE_VOID
boolean
jboolean
KNI_RETURNTYPE_BOOLEAN
byte
jbyte
KNI_RETURNTYPE_BYTE
char
jchar
KNI_RETURNTYPE_CHAR
short
jshort
KNI_RETURNTYPE_SHORT
int
jint
KNI_RETURNTYPE_INT
long
jlong
KNI_RETURNTYPE_LONG
float
jfloat
KNI_RETURNTYPE_FLOAT
double
jdouble
KNI_RETURNTYPE_DOUBLE
<object ref>
jobject
KNI_RETURNTYPE_OBJECT

The presence of the return types allows the virtual machine implementing the K Native Interface to use different implementation techniques for returning values back from native functions. For example, in the KVM implementation of the KNI, the actual C data type of the KNI return types is ‘void’, whereas other virtual machines may need to map the return types to applicable VM-specific data types.

4.2 Field IDs

Field IDs are regular C pointer types:

    struct _jfieldID; /* opaque C structure */ 
    typedef struct _jfieldID* jfieldID; /* field ID */ 

Note that fieldID is intended to be an opaque type. That is, the KNI programmer may not rely on the internal structure of this type, as its definition may vary from one virtual machine implementation to another.

4.3 String Formats

The KNI uses UTF-8 strings in the const char* format for reading class names and field names that are provided as parameters to certain KNI functions. These UTF-8 strings are converted to Unicode strings inside the KNI implementation as necessary. Some KNI operations read and return data in buffers that are assumed to be large enough for Unicode strings (each Unicode character is 16 bits wide.)

4.3.1 UTF-8 Strings

UTF-8 strings are encoded so that character sequences that contain only non-null ASCII characters can be represented using only one byte per character, but characters of up to 16 bits can be represented. All characters in the range ‘\u0001’ to ‘\u007f’ are represented by a single byte, as follows:

0 
bits 6–0 

The seven bits of data in the byte give the value of the character that is represented. The null character (‘\u0000’) and characters in the range ‘\u0080’ to ‘\u07ff’ are represented by a pair of bytes, x and y, as follows:

x:

1 
1 
0 
bits 10-6 

y:

1 
0 
bits 5-0 

The bytes represent the character with the value ((x & 0x1f) << 6) + (y & 0x3f).

Characters in the range ‘\u0800’ to ‘\uffff’ are represented by three bytes, x, y, and z, as follows:

x:

1 
1 
1 
0 
bits 15-12 

y:

1 
0 
bits 11-6 

z:

1 
 
bits 5-0 

The character with the value ((x & 0xf) << 12) + ((y & 0x3f) << 6) + (z & 0x3f) is represented by the three bytes.

There are two differences between this format and the standard UTF-8 format. First, the null byte (byte)0 is encoded using the two-byte format rather than the one-byte format. This means that KNI UTF-8 strings never have embedded nulls. Second, only the one-byte, two-byte, and three-byte formats are used. KNI does not recognize the longer UTF-8 formats.

4.3.2 Class Descriptors

A class descriptor represents the name of a class or an interface. It can be derived from a fully qualified class or interface name as defined in The Java Language Specification by substituting the “.” character with the “/” character. For instance, the class descriptor for java.lang.String is:

java/lang/String

Array classes are formed using the “[” character followed by the field descriptor of the element type. The class descriptor for “int[]” is:

[I

and the class descriptor for “double[][][]” is:

[[[D

4.3.3 Field Descriptors

Table TABLE 4 shows the field descriptors for the primitive types exported by the KNI.

TABLE 4  –  The field descriptors for the KNI primitive types
Field Descriptor
The Java language type
Z
boolean
B
byte
C
char
S
short
I
int
J
long
F
float
D
double

The field descriptors of reference types begin with the “L” character, followed by the class descriptor, and terminated by the “;” character. Field descriptors of array types are formed following the same rule as class descriptors of array classes. TABLE 5 contains examples of field descriptors for reference types and their Java programming language counterparts.

TABLE 5  –  Examples of field descriptors for reference types
Field Descriptor
The Java language type
Ljava/lang/String;”
String
“[I”
int[]
“[Ljava/lang/Object;”
java.lang.Object[]

4.4 Constants

File ‘kni.h’ defines certain constants and macros that are commonly used in native functions. These include the following:

KNIEXPORT is a macro used to specify the calling and linkage conventions of both KNI functions and native method implementations. The programmer is recommended to place the KNIEXPORT macro before the function return type. For example:

    KNIEXPORT void Java_mypackage_Cls_f(); 

is the prototype for a C function that implements method f of class Cls in package mypackage.

KNI_FALSE and KNI_TRUE are constants defined for the jboolean type:

    #define KNI_FALSE 0 
    #define KNI_TRUE 1 

KNI_OK represents the successful return value of a few KNI functions, and KNI_ERR is sometimes used to represent error conditions.

    #define KNI_OK 0 
    #define KNI_ERR -1 

KNI_VERSION represents the KNI version number.

    #define KNI_VERSION 0x00010000 /* KNI version 1.0 */ 

 


Contents Previous Next KNI Specification
K Native Interface (KNI), 1.0