目次 | 前へ | 次へ

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 文字だけが含まれる文字シーケンスが表現できるようにエンコードされていますが、Unicode 文字もすべて表現できます。

次のように、\u0001 から \u007F の範囲のすべての文字が 1 バイトで表現されます。

0 ビット 6-0

バイトのうち 7 ビットのデータは、表現されている文字の値を示します。

null 文字 ('\u0000') および '\u0080' から '\u07FF' の範囲の文字は、次のように x と y の一対のバイトで表現されます。

x:

1 1 0 ビット 10-6
y:
1 0 ビット 5-0

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

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

x:

1 1 1 0 ビット 15-12
y:
1 0 ビット 11-6
z:
1 0 ビット 5-0

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

U+FFFF より大きなコードポイントを持つ文字 (いわゆる補助文字) は、UTF-16 表現の 2 つの代理コード単位を別々にエンコードすることで表現されます。代理コード単位はそれぞれ 3 バイトで表現されます。つまり、補助文字は、次のように uvwxyz の 6 バイトで表現されます。

u:

1 1 1 0 1 1 0 1
v:
1 0 1 0 (ビット 20-16) - 1
w:
1 0 ビット 15-10
x:
1 1 1 0 1 1 0 1
y:
1 0 1 1 ビット 9-6
z:
1 0 ビット 5-0

0x10000+((v&0x0f)<<16)+((w&0x3f)<<10)+(y&0x0f)<<6)+(z&0x3f) という値の文字は、6 バイトで表現されます。

マルチバイト文字のバイトは、class ファイルにビッグエンディアン順 (高位バイトが先) に格納されています。

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

標準 UTF-8 形式に関する詳細は、『The Unicode Standard, Version 4.0』の「3.9 Unicode Encoding Forms」のセクションを参照してください。

 


目次 | 前へ | 次へ

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