目次 | 前へ | 次へ

JNI の型とデータ構造


第 3 章

この章では、JNI がどのように Java の型をネイティブ C の型にマッピングするかを解説します。

プリミティブ型

表 3-1 は、Java のプリミティブ型およびそれらのマシン依存のネイティブ型との対応について説明しています。

表 3-1 プリミティブ型とネイティブ型
Java 型
ネイティブ型
説明
boolean
jboolean
unsigned 8 ビット
byte
jbyte
signed 8 ビット
char
jchar
unsigned 16 ビット
short
jshort
signed 16 ビット
int
jint
signed 32 ビット
long
jlong
signed 64 ビット
float
jfloat
32 ビット
double
jdouble
64 ビット
void
void
なし

次の定義は、利便性のため提供されています。

#define JNI_FALSE  0 
#define JNI_TRUE   1 

jsize 整数型は、基本的なインデックスおよびサイズを記述するために使用されます。

typedef jint jsize; 

参照型

JNI には、各種の Java オブジェクトに対応する多くの参照型が含まれています。JNI 参照型は、図 3-1 に示すように、階層構造になっています。

階層の最上部は jobject です。jobject のサブクラスは、jclass、jstring、jarray、および jthrowable です。jarray のサブクラスは、jobjectArray、jbooleanArray、jbyteArray、jcharArray、jshortArray、jintArray、jlongArray、jfloatArray、jdoubleArray です。

図 3-1 参照型の階層

C では、その他すべての JNI 参照型は、jobject と同じように定義されています。たとえば、

typedef jobject jclass; 

C++ では、JNI はダミークラスのセットを導入して、サブタイプ関係を強制します。たとえば、

class _jobject {}; 
class _jclass : public _jobject {}; 
... 
typedef _jobject *jobject; 
typedef _jclass *jclass; 

フィールドとメソッド ID

フィールドとメソッド ID は、次のように正規の C ポインタ型です。

struct _jfieldID;              /* opaque structure */ 
typedef struct _jfieldID *jfieldID;   /* field IDs */ 
 
struct _jmethodID;              /* opaque structure */ 
typedef struct _jmethodID *jmethodID; /* method IDs */ 

値の型

jvalue 共用体型は、引数配列で要素型として使用されます。これは次のように宣言されます。

typedef union jvalue { 
    jboolean z; 
    jbyte    b; 
    jchar    c; 
    jshort   s; 
    jint     i; 
    jlong    j; 
    jfloat   f; 
    jdouble  d; 
    jobject  l; 
} jvalue; 

型のシグニチャー

JNI は、Java VM の型シグニチャー表現を使用します。表 3-2 は、これらの型シグニチャーを示しています。

表 3-2 Java VM の型シグニチャー
型シグニチャー
Java 型
Z
boolean
B
byte
C
char
S
short
I
int
J
long
F
float
D
double
L fully-qualified-class ;
完全修飾のクラス
[ type
type []
( arg-types ) ret-type
メソッドの型

たとえば、次の Java メソッドには、

long f (int n, String s, int[] arr); 

次のような型のシグニチャーがあります。

(ILjava/lang/String;[I)J 

UTF-8 文字列

JNI は UTF-8 文字列を使用して各種の文字列型を表現します。UTF-8 文字列は Java VM によって使用されるものと同じです。UTF-8 文字列は、1 文字につき 1 バイトだけを使用して null 以外の ASCII 文字だけが含まれる文字シーケンスが表現できるようにエンコードされており、16 ビットまでの文字を表現できます。次のように、\u0001 から \u007F の範囲のすべての文字が 1 バイトで表現されます。

先頭の位置には 0 で構成されるバイト、その後に文字の値を表現するビット 0 から 6 までのビットが続きます。

バイトのうち 7 ビットのデータは、表現されている文字の値を示します。次のように、null 文字 (\u000) および \u0080 to \u07FF の範囲の文字は xy の一対のバイトで表現されます。

先頭から 3 つの位置には 110 の x バイト、その後に文字の値を表現するビット 6 から 10 までのビットが続きます。先頭から 2 つの位置には 10 の y バイト、その後に文字の値を表現するビット 0 から 5 までのビットが続きます。

このバイトは、((x&0x1f)<<6)+(y&0x3f) の値で文字を表現します。

\u0800 から \uFFFF の範囲の文字は、次のように xy、および z の 3 バイトで表現されます。

1110 の x バイト、その後に文字を表現するビット 12 から 15 までのビットが続きます。10 の y バイト、その後にビット 6 から 11 までが続きます。10 の z バイト、その後にビット 0 から 5 までが続きます。

((x&0xf)<<12)+(y&0x3f)<<6)+(z&0x3f) という値の文字は、3 バイトで表現されます。

この形式と「標準」UTF-8 形式の間には、2 つの相違点があります。第一は、null バイト (byte)0 が、1 バイト形式でなく 2 バイト形式でエンコードされていることです。このことは Java VM UTF-8 文字列が null を組み込むことがないことを意味します。第ニは、1 バイト、2 バイト、および 3 バイト形式だけが使用されていることです。Java VM はこれより長い UTF-8 形式を認識しません。

 


目次 | 前へ | 次へ

Copyright © 1993, 2013, Oracle and/or its affiliates. All rights reserved.