7

JNI API に慣れようとしていますが、サンプルの C++ プログラムをコンパイルすることができません。Linux でコンパイルして実行する同じサンプルを入手しましたが (以下のリンクに質問を投稿した後)、Windows でコンパイルすることはできません。私はmingw g ++を使用しています。すべてのインクルード パスを Windows パスに変更しました。jni.h はコンパイル時に配置されますが、jvm.dll には配置されません。

`JNI_CreateJavaVM' linux への未定義の参照

コンパイルに使用しようとしたコマンドは次のとおりです。

g++ -g -I"C:\Program Files (x86)\Java\jdk1.7.0_21\include" -I"C:\Program Files (x86)\Java\jdk1.7.0_21\include\win32" -L"C:\Program Files (x86)\Java\jdk1.7.0_21\jre\bin\server" callJava.cpp -ljvm

と...

**same as above with the additional** : -L"C:\Program Files (x86)\Java\jdk1.7.0_21\lib"

私が得るエラーは次のとおりです。

undefined reference to `_imp__JNI_CreateJavaVM@12'

そしてコンパイルされているcpp:

#include <jni.h>

int main(){

    //firstTest();
    JavaVM *jvm;
    JNIEnv *env;

    JavaVMInitArgs vm_args;
    JavaVMOption options[1];
    options[0].optionString = "-Djava.class.path=C:/Users/Ron/Dropbox/jni/simple/ctojava/win";
    vm_args.version = JNI_VERSION_1_6;
    vm_args.options = options;
    vm_args.nOptions = 1;
    vm_args.ignoreUnrecognized = JNI_FALSE;

    int res = JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args);

    jclass cls = env->FindClass("Hello");
    jmethodID mid = env->GetStaticMethodID(cls, "staticInt", "(I)I");
    env->CallStaticVoidMethod(cls, mid,10);

    jvm->DestroyJavaVM();
}

多くの例を見てきましたが、まだ解決策が見つかりません。どんな助けでも大歓迎です!

更新: -L"path_to_jvm" を削除するとエラーが発生するため、jvm.dll が配置されていると確信しています。

mingw32/bin/ld.exe: cannot find -ljvm

私が言ったように、この正確なアプローチはLinuxで機能します.Windowsには他に何が欠けていますか?

4

2 に答える 2

3

あなたが遭遇した問題は、名前の装飾の問題として簡単に要約できます。リンカは指定された名前の関数を見つけることができませんでしたjvm.dll。.

あなたが得た最初のエラーを見る:

undefined reference to '_imp__JNI_CreateJavaVM@12'

それは2つのことを示唆しています:

  1. @12末尾の接尾辞JNI_CreateJavaVMは、stdcall 規則を使用していると思われることを示しています。
  2. _imp_プレフィックスは、この関数がエクスポート テーブルに表示されるこの関数を持つ、外部から読み込まれた dll にリダイレクトするインポート ライブラリからのものであることを示します。

の関数プロトタイプjni.h:

_JNI_IMPORT_OR_EXPORT_ 
jint JNICALL JNI_CreateJavaVM(JavaVM **, void **, void *);

前処理後はおそらく次のようになります。

__declspec(dllimport) jint __stdcall
JNI_CreateJavaVM(JavaVM **, void **, void *);

mingw に付属の gnu リンカは.a、msvc の COFF 形式のシンボル.lib.dll直接操作できるようになりました。jvm.dll元のコマンドでは、提供された検索パス ( )でしか見つからなかった-L ...ため、それを使用しようとしました。

問題は、jvm.dllエクスポート テーブルJNI_CreateJavaVM関数が装飾されていないため、cdecl 関数のように見えることです。この名前はリンカーが期待するものと一致しないため、未定義の参照エラーが発生します。

Java Dev Kit を見ると、jdk1.7.0_21\lib\jvm.libこのシンボルに適切な名前の装飾が施されたインポート ライブラリが含まれています。改訂されたコマンドは、検索パスに追加することで、 ではなく-L jdk1.7.0_21\libに対してリンクしているため、機能します。jvm.libjvm.dll

于 2013-06-05T20:25:28.060 に答える