ネイティブメソッドを実装する |
整数、フロート、論理型値のようなプリミティブ型や、オブジェクト、配列、文字列 のようなリファレンス型など、どのような型の値でもネイティブメソッドから返すことができる。プリミティブ型を返す
ネイティブメソッドの返り値の型は、メソッドの Java 定義に指定する。InputFile クラスには値を返すネイティブメソッドが 2 つある。open()
メソッ ドは論理型値を返し、read()
メソッドは整数を返す。また、OutputFile クラスにも値を返すネイティブメソッドが 2 つある。// in InputFile.java public native boolean open(); public native int read(byte b[], int len);open()
メソッドは論理値型を返し、write()
メソッド は整数を返す。ネイティブメソッドへ引き渡すパラメータの場合と同様、ネイティブメソッド からの返り値のデータ型は、呼び出し元の Java プログラムが受け入れるデータ型と一致するとは限らない。表に Java での型と C 言語での型との対応を示す。C 言語で書かれたネイティブメソッドから正しいデータを返す には、この表の対応づけに従う必要がある。// in OutputFile.java public native boolean open(); public native int write(byte b[], int len);この表で、Java の論理型値と Java の整数がどちらも C 言語のロング整数と対応していることに注意する。したがって、次の例の関数はすべて
long
の値を返す。// in InputFileImpl.c long InputFile_open(struct HInputFile *this) . . . long InputFile_read(struct HInputFile *this, HArrayOfByte *buffer, long count) // in OutputFileImpl.c long OutputFile_write(struct HOutputFile *this, HArrayOfByte *buffer, long count) . . . long OutputFile_open(struct HOutputFile *this)複合型を返す
ネイティブメソッドの返り値を使用して、リファレンスデータ型を返すこともできる 。InputFile クラスと OutputFile クラスはどちらもこの操作を行っていない。しかし、 InputFile クラスのread()
メソッドが、メソッドの返り値経由で読みこまれたバイトを返すものと想定してみる。この場合、メソッドの Java 宣言は次 のようになる。この文は// in InputFile.java public native byte[] read(int len);read()
メソッドがバイト配列を返すと宣言している。read()
を実装するネイティブ言語関数は、今回はバイト配列を返すよ う宣言しなければならない。リファレンスデータ型の返り値も、リファレンスデータ 型の引数と同じ規則に従う。ネイティブ言語関数は、構造体へのハンドルを返すよう に宣言しなければならない。構造体名は 複雑なデータ型を引き渡すで説明しているように、クラス名から得られる。したがって、InputFile_read()
関数の新しい宣言は次のようになる。// in InputFileImpl.c HArrayOfByte * InputFile_read(struct HInputFile *this, long count)引数を通してネイティブメソッドにデータを返す
複数のデータ値を返す場合など、返り値ではなく引数を通してネイティブメソッドへデータを返す方が都合のよい場合がある。プリミティブデータ型は値によってネイティブメソッドへ引き渡される。つまり、引数へのリファレンスではなく引数の値が呼び出しスタックに置かれる。このため、プリミティブデータ型の引数を通してネイティブメソッドから値を返すことはできず、 リファレンスデータ型の引数を使用する必要がある。InputFile の
read()
メソッドはこの方法をとっている。つまり、読み取られたバイ トをメソッドのバイト配列引数を通して返しているのである。InputFile_read()
関数は入力ファイルからバイトを取り出し、バイト配列の本体に配置する。プリミティブ値を返したい場合は、まず関数の返り値の使用を考える。プリミテ ィブ値を返すためにどうしても引数を使用する必要がある場合は、Integer、Float、 Boolean のような java.lang のデータ型ラッパークラスのどれかに引数をラップしなければならない。
ネイティブメソッドを実装する |