4

JNI を使用して Java プログラムから C コードにアクセスしようとしているテスト ケースがあります。必要な手順は次のとおりです。

1. ネイティブ メソッドを呼び出す Java プログラム :

public class RunnerClass{
    public native void win32_svc_install();
    static{
        System.loadLibrary("testDll");
                System.out.println("library loaded successfully");   
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new RunnerClass().win32_svc_install();
    }

}

2..classファイルが生成され、対応する.hファイルが作成された後、ネイティブ メソッドの実装を.cファイル内に配置します。

    /* DO NOT EDIT THIS FILE - it is machine generated */
//RunnerClass.h

#include <jni.h>
/* Header for class RunnerClass */

#ifndef _Included_RunnerClass
#define _Included_RunnerClass
#ifdef __cplusplus
extern "C" {
#endif/*
 * Class:     RunnerClass
 * Method:    nx_win32_svc_install
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_RunnerClass_win32_1svc_1install
  (JNIEnv *, jobject);#ifdef __cplusplus
}
#endif
#endif

このRunnerClass.cファイルには、ネイティブ メソッドの実装が含まれています。このメソッドが正確にServiceManager行うことは、それを利用するためにウィンドウの を呼び出すことです。私の Java プログラムは、これらのアクションを実行する必要があります。

testDll.dllが作成された後に問題が発生します。Java コードを解釈する前に、必要な library( testDll)のライブラリ パスをjava.library.path.

プログラムを実行すると、ライブラリが読み込まれますがUnsatisfiedLinkError、ネイティブ メソッドにスローされます。正確なエラーは次のとおりです。

Exception in thread "main" hello ,java.lang.UnsatisfiedLinkError: RunnerClass.win32_svc_install(ILjava/lang/String;)V
    at RunnerClass.win32_svc_install(Native Method)
    at RunnerClass.main(MainWs.java:58)

私は多くの調査を行い、ロードされているライブラリでプログラムがネイティブメソッドの実装を見つけることができないため、例外がスローされることをはるかに理解しました。

4

1 に答える 1

1

例外は何らかの形でコードと一致しません。Java では、関数を次のように宣言します。

public native void win32_svc_install();

C++ では、関数を次のように宣言します。

JNIEXPORT void JNICALL Java_RunnerClass_win32_1svc_1install (JNIEnv *, jobject);

と宣言すべきだと思います。

JNIEXPORT void JNICALL Java_RunnerClass_win32_svc_install (JNIEnv *, jobject);

しかし、c++ 宣言の奇妙な "1" 以外にも、別の問題があるようです。どちらの関数も、引数なしの void 関数として正しく宣言されています。

ただし、例外は、同じ名前の void 関数を探しているが、整数と文字列の引数を使用していると述べています。

RunnerClass.win32_svc_install(ILjava/lang/String;)V

あなたのコードを見ると、その理由が想像できません。C++ 関数の 1 つの名前を変更して再現しようとしました。次の満たされていないリンクの例外は、定義されたパラメーターを正しく示しています。

于 2013-05-26T22:19:49.480 に答える