2

JNIを介してC関数を呼び出して「HelloWorld」を出力する単純なJavaプログラムを作成しようとしています。すべてがエラーなしでコンパイルされますが、プログラムを実行すると、「UnsatisfiedLinkError:Ca n'tfinddependentlibrary」が表示されます。

Dependency Walkerとdumpbinによると、唯一の依存関係はC:\ Windows \ System32にある「kernel32.dll」と、同じくSystem32にあるその依存関係です。

呼び出し

    System.loadLibrary("Kernel32");

エラーなしで戻りますが、印刷関数を含むHello.dllをロードしてもエラーがスローされます。

誰かがこれを引き起こしている可能性があることを知っていますか?

編集:

Dependency Walkerは、2つの警告/エラーを出します。

-エラー:暗黙的に依存するモジュールにエクスポート機能がないため、少なくとも1つのモジュールに未解決のインポートがあります。

-エラー:異なるCPUタイプのモジュールが見つかりました。

編集:

詳細は次のとおりです。Windows764ビットを実行しており、.dllをcl(Visual Studio 2010)でコンパイルしています。

私のJavaコードHello.java:

    public class Hello
    {
        public static native void hello();

        public static void main(String[] args)
        {
            hello();
        }

        static
        {
            // Extra dependencies load with no error
            System.loadLibrary("NTDLL");
            System.loadLibrary("KERNELBASE");
            System.loadLibrary("KERNEL32");
            System.loadLibrary("Hello"); // Throws UnsatisfiedLinkError
        }
    }

エラーなしでjavaファイルをコンパイルし、javah-jniを使用してCヘッダーHello.hを生成できます。

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class Hello */

    #ifndef _Included_Hello
    #define _Included_Hello
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     Hello
     * Method:    hello
     * Signature: ()V
     */
    JNIEXPORT void JNICALL Java_Hello_hello
      (JNIEnv *, jclass);

    #ifdef __cplusplus
    }
    #endif
    #endif

Hello.cにヘッダーを実装します。

    #include <stdio.h>
    #include <jni.h>
    #include "Hello.h"
    #pragma comment(linker, "/EXPORT:Java_Hello_hello=_Java_Hello_hello@8")

    JNIEXPORT void JNICALL
    Java_Hello_hello(JNIEnv* env, jclass class)
    {
        printf("Hello World\n");
        return;
    }

Cコードはcl(tccも試しましたが)を使用してHello.dllにコンパイルされます。Hello.dllはjava.classと同じディレクトリに格納されています。

4

3 に答える 3

2

私の問題は、64ビットシステムとJavaインストールおよび32ビットCコンパイラの組み合わせであったようです。

既定では、Visual C ++clコンパイラは32ビットアプリケーションを生成します。これにより、64ビットJavaでロードするとエラーが発生しました。アプリケーションをWindowsSDK7.1 64ビットコンパイラでコンパイルしましたが、エラーなしで実行され、DependencyWalkerの警告も削除されました。

于 2012-08-26T18:49:30.270 に答える
1

私はJNIを学校の最終プロジェクトで働かせようとしましたが、1か月のヘッドバンギングの後、代替案を探すことになりました。代わりにJavaNativeAccessを試してください。Windows(.dll)およびLinux(.so)上の任意の共有ライブラリから任意のC関数を呼び出すことができ、一部のWin32関数の便利なメソッドもあります。ネイティブコードを共有ライブラリにコンパイルしてから、JNAを使用してライブラリに動的にリンクし、関数を呼び出します。すべてが動的にロードされるため、JNIよりも大幅に遅いと言われていますが、パフォーマンスへの影響はありませんでした。

Cコンパイラが関数名をどのように壊すかを理解するために-何かに変える-私はDLLエクスポートビューアをお勧めしstrlenますダウンロードリンクは下部にあります)。Linuxに同様のツールがあるかどうかはわかりません。_strlen@4

于 2012-08-26T05:47:46.427 に答える
0

あなたはどちらかをする必要があります

  • DLLをwindows\system32\フォルダーに配置します
  • コマンドラインでjava.library.pathを指定します
于 2012-08-26T18:05:02.417 に答える