2014年3月15日土曜日

JNI (Java Native Interface) (4) nativeメソッドのロードと呼び出すについて

nativeメソッドは、通常のJavaメソッドと同じように呼び出せます。

ただし、以下の点に注意しましょう。

  • System.loadLibrary を呼び出す。
  • nativeメソッドを宣言しているクラスの中に、staticな初期化ブロックを置いて呼び出すのが一般的
  • staticな初期化ブロックのコードは、クラスを初期化するときに実行される
  • クラスは初めてアクティブに使われたとき (= クラスが定義したメソッドを呼び出す)に初期化される
  • ロードしていなかったり、失敗している場合にはJVMが「java.lang.UnsatisfiedLnkError」を投げる(getMessageで見つからなかったnativeメソッド名を取得できる)
  • 共有オブジェクトライブラリのファイルは、環境変数LD_LIBRARY_PATHに指定したディレクトリの中にあることが必要
  • LD_LIBRARY_PATHは、「;」で区切って複数のディレクトリを指定可能。以下で確認する
% echo $LD_LIBRARY_PATH
  • ネイティブライブラリのロードを頑丈にするには、以下のようにします
次に、ロードに関するよくある間違いを見てみましょう。

検索パスのミス

  • ロードに失敗すると、最初にnativeメソッドを呼び出そうとしたとき、java.lang.UnsatisfiedLinkErrorが投げられます。
  • mainでロードしている場合、ロードにトライしたとき、上記と同様なことが起こります。

ライブラリ名の間違い

  •  上記と同じエラーが起きます。
  • javaデバッガで実行するとき、Nativeライブラリの名前に_gを要求することがある。デバッグでのみ問題がおこるときは、[ライブラリ名]_g.so や [ライブラリ名]_g.dll を準備してみるとよいです。

シグネチャの不一致

  •  nativeメソッドの仮引数の個数と型が、関数プロトタイプと一致しない場合、java.lang.UnsatisfiedLinkErrorが投げられる。nativeメソッドを変更したら、必ずjavahでヘッダを再生成することを進めます。package変更によっても起こります。

java.lang.UnsatisfiedLinkError が投げられたとき、上記を見直してみるとよいでしょう。

次は、変数とメソッド呼び出し についてです。


0 件のコメント:

コメントを投稿