2016-10-03 18 views
0

System.loadLibrary( "")を使用して静的にコンパイルされたライブラリをJavaからロードする際に問題がありますが、それを動的にコンパイルしたライブラリとしてロードできます。私はJDK 8を使用していますが、* .cppファイルと* .hファイルにJNI_OnLoad_Lを指定すると、System.loadLibrary( "")を介して静的ライブラリをロードできます。静的にコンパイルされたライブラリをJavaでロードする

マイkdu_jni.hがあります

extern "C" 
JNIEXPORT jint JNICALL JNI_OnLoad_kdu_1jni(JavaVM *, void *); 

マイkdu_jni.cppがあります

JNIEXPORT jint JNICALL JNI_OnLoad_kdu_1jni(JavaVM *vm, void *reserved) 
{ 
    return JNI_VERSION_1_8; 
} 

私が実行しようとすると、私は私がjava.library.pathディレクトリ内libkdu_jni.aファイルを持っていますコンパイルされたバージョンで。私はそれを動的にロードしようとすると、同じディレクトリ内のlibkdu_jni.soファイルで正常に動作しています。静的なファイル(libkdu_jni.a)をしようとすると、私が手:

Exception in thread "main" java.lang.UnsatisfiedLinkError: no kdu_jni in java.library.path 
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867) 
    at java.lang.Runtime.loadLibrary0(Runtime.java:870) 
    at java.lang.System.loadLibrary(System.java:1122) 

私は.Aファイルをロードしようとする前の.soファイルを取り出しました。

私が間違っていることはわかりません。私はlibkdu_jni.aファイルのJNI_OnLoad_kdu_1jni()も見ているとは思えません。なぜなら、私はそこに例外を入れてしまい、それが投げられるのを見ていないからです。 JNI_OnLoad_kdu_jni()、JNI_OnLoad_kdu_1jni()、JNI_OnLoad()などいくつかの繰り返しを試みました。

アイデアはありますか?

+2

JNI_OnLoad_kdu_1jniの定義は、 'extern" C "'で囲まれていますか?私が試みることを提案する唯一の他の事は、ライブラリをL.aのような単純なものに命名することです。 –

+0

コンパイルされたライブラリを静的にロードすることはできません。それらを.soまたは.dllにリンクする必要があります。あなたの質問は理にかなっていません。 – EJP

+0

@EJP Java8にはスタティックライブラリを読み込む機能が追加されました。私はあなたのようなコメントでチャイムしようとしていましたが、JEP 178は物事を変えます。 –

答えて

2

* .cppファイルと* .hファイルにJNI_OnLoad_Lを指定すると、System.loadLibrary( "")を介して静的ライブラリを読み込むことができます。

あなたの理解は間違っています。 .aファイルを動的に読み込むことはできません。例えば、Cライブラリに:

  • 赤外線ライブラリ参照がライブラリ外
  • 参考文献のいずれかに解決されていない解決されない:これは、任意の方法形状又は形態で実行可能ではありません。

リンクステップは必須であり、JVMはそれを実行しません。あなたが読んだことは、ライブラリにJVMに静的にリンクされて適用されます。

+0

私は、glibcのバージョンが異なるプラットフォームの動的libをコンパイルしていると思います。これはおそらく、JVMを含む実行可能ファイルをコンパイルするより簡単です。 – ksclarke

+1

好みのglibcを動的ライブラリに静的にリンクするのではなく、ダイナミックライブラリを動的ライブラリに使用することができます。 – EJP

+0

ありがとうございます、私はここに新しい領域です。それが可能であれば、私はその方向性について研究します。 – ksclarke

0

関数名にJNI_OnLoad_kdu_jniを試してみることをお勧めします。それでも機能しない場合は、アンダースコアを含むライブラリ名では機能しない可能性があります。

---オリジナルのポストは、以下の---

を前のJava 8に、唯一の共有オブジェクトライブラリがサポートされていました。

これは、静的ライブラリがJava 8かどうかを知るためには、ライブラリ内に新しい関数を実装する必要があります。

JNI_OnLoad_libname must return a value of JNI_VERSION_1_8 or higher. 

あなたのコードは動的に動作しますが、静的ではないため、おそらくこの機能は存在しないと推測しています。

ロードを:読むために改訂されるjava.lang.System.loadLibraryの

仕様と java.lang.Runtime.loadLibrary方法:JEP 178の部分は、以下の私はこれを信じるように導きますlibname引き数で指定されたネイティブ・ライブラリー。 libnameには、プラットフォーム固有の接頭辞、ファイル拡張子、 またはパスを含めることはできません。

libnameというネイティブライブラリがVMに静的にリンクされている場合、 ライブラリによってエクスポートされたJNI_OnLoad_libname関数が呼び出されます。詳細は、「JNI仕様」を参照してください。

それ以外の場合、libnameはシステムライブラリの場所からロードされ、 実装依存の方法でネイティブライブラリイメージにマッピングされます。

Also the notes in the enhancement echo this sentiment

The source code for the loader is helpful

は私がデバッグ(GDB)の下でのjavaを起動し、 Java_java_lang_ClassLoader_00024NativeLibrary_findBuiltinLibの中でブレークポイントを置くと思います。あなたは正しい、多くの素晴らしい例はありません。

+0

* '静的にJVMにリンクされています' *は '静的コンパイルされたライブラリ'と同じではありません。 – EJP

+0

@ EJPありがとうございます。私はそれを見て、はい、それは実際にはサポートされていないときに静的ライブラリを動的にロードしようとしているようです。 –

関連する問題