やりたかったことは大昔のシステムのDLLの関数と
それをリファインしたjavaのライブラリとの動作のチェックなんだけどね。
(1)旧DLLを単体で呼び出し、動作確認 (C++)
(2)ラッパーDLLを作成し、サンプルJavaから呼び出し(C++,java)
(3)javaのライブラリをサンプルjavaから呼び出し(java)
(4)比較ロジックを作成、呼び出し部はスタブにて実行(java)
ココまでは順調だった。
(5)パッケージ分けし、JNIコールも組み込み、DLL内処理に
printfデバッグを仕込んでおき作動させる -> NG
( ゚Д゚)ハァ?
(6)DLLを単体で呼び出してみる -> OK
例外はUnsatisfiedLinkError 。
System.loadLibraryは成功しているので、これは関数が見つからない
という意味。調べると、javah -jniの使い方に問題があった模様。
・パッケージ名を持っている場合は、そのクラス階層で直接javahしてはダメ。
JNIメソッド名には完全修飾名であるので、呼び出したときにUnsatisfiedLinkErrorになる。
WEB上にたくさんあるサンプルではほとんどが無名パッケージなので、非常に気づきにくい。
javahのヘルプメッセージを凝視すると、
>javah
使い方: javah [options] classes
[options] には次のものがあります。
-help ヘルプメッセージを表示して終了する
-classpath path クラスをロードするバス
-bootclasspath path ブートストラップクラスをロードするパス
-d dir 出力ディレクトリ
-o file 出力ファイル (-d か -o のどちらか一方を使用する)
-jni JNI 形式のヘッダファイルを生成する (デフォルト)
-old JDK1.0 形式のヘッダファイルを生成する
-stubs スタブファイルを生成する
-version バージョン情報を表示する
-verbose 詳細な出力を行う
-force 常に出力ファイルを書き込む
classes は完全指定の名前で指定します (java.lang.Object など)。
しっかり書いてある ('A`)ウボア
例えば、jp.hoge.TestJni だった場合、cd jp/hoge/ javah -jni TestJni ではNG
javah -classpath ./ -jni jp.hoge.TestJni とやらないと完全修飾名でヘッダが作成されない。
(7)でもUnsatisfiedLinkError。(;´Д`)ハァハァ
(8)試しにパッケージを取り払って、ヘッダも作り直してみる
→ OK
( ゚д゚)??
やりたいことは検証のみで、時間も迫っていたため
妥協したが、どうも納得いかない。
同様の事例も見あたらないし、メソッド名も間違い無い。
DependencyWalkerで公開関数を見てみたが、ちゃんと公開できてる。
うーむ・・。また折りをみて確認しよう。
参考リンク


