2016-12-07 12 views
-1

私はUnsatisfiedLinkErrorについて多くの質問を受けましたが、私の問題は何かを知っています。私はスレッドでJNI java.lang.UnsatisfiedLinkError、メソッドをリンクできません

例外を取得し、 "メイン" ます。java.lang.UnsatisfiedLinkError:Test.initCamera(Ljava/LANG /文字列; Ljava/LANG /文字列; Ljava/LANG /文字列; Ljava/LANG /文字列;)J

これは、dllがロードされているが、そのメソッドを見つけることができないことを意味します。しかし、私は私のソースコードとJavaコードをチェックしました。メソッド名と引数は大丈夫です。自分のコードに何が問題なのか分かりません。

これは私のコードです。

のJava:

public class Test { 
public native long initCamera(String ip,String port,String username,String pwd); 
public native int snapPic(long id,String savePath,int no); 
static{ 
    System.loadLibrary("dhconfigsdk"); 
    System.loadLibrary("dhnetsdk"); 
    System.loadLibrary("dhplay"); 
    System.loadLibrary("CameraCatcher"); 
} 
public static void main(String[] args) { 
    // TODO Auto-generated method stub 
    Test tNative = new Test(); 
    String ip="192.108.1.108"; 
    String port="37777"; 
    String username="admin"; 
    String pwd="123456"; 
    long cameraId=tNative.initCamera(ip,port,username,pwd); 
    System.out.println(cameraId); 
    String savePath="D:/"; 
    int number=tNative.snapPic(cameraId,savePath,0); 
} 
} 

C++:

JNIEXPORT jlong JNICALL Java_CameraCatcher_initCamera 
(JNIEnv * env, jclass c, jstring arg_ip, jstring arg_port, jstring arg_username, jstring arg_pwd) 
{ 
    ...... 
    return lLogin; 
} 


JNIEXPORT jint JNICALL Java_CameraCatcher_snapPic 
(JNIEnv * env, jclass c, jlong arg_id, jstring arg_path, jint arg_no) 
{ 
    ..... 
    return 12; 
} 

これは本当に私を狂わせます。

更新1: お返事ありがとうございます。 @Mr Tarikが示したように私のコードを変更しました。

のJava:

public class CameraCatcher { 
    static{ 
     System.loadLibrary("CameraCatcher"); 
    } 
    public native long initCamera(String ip,String port,String username,String pwd); 
    public native int snapPic(long id,String savePath,int no); 
    public static void main(String[] args) 
    { 
     CameraCatcher tNative = new CameraCatcher(); 
     String ip="192.108.1.108"; 
     String port="37777"; 
     String username="admin"; 
     String pwd="123456"; 
     long cameraId=tNative.initCamera(ip,port,username,pwd); 
     System.out.println(cameraId); 
     String savePath="D:/project/j2ee/Example/result"; 
     int number=tNative.snapPic(cameraId,savePath,0); 
    } 
} 

それから私は、ヘッダファイルを生成するためのjavahを使用します。

#include <jni.h> 

#ifndef _Included_CameraCatcher 
#define _Included_CameraCatcher 
#ifdef __cplusplus 
extern "C" { 
#endif 
/* 
* Class:  CameraCatcher 
* Method: initCamera 
* Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)J 
*/ 
JNIEXPORT jlong JNICALL Java_CameraCatcher_initCamera 
    (JNIEnv *, jobject, jstring, jstring, jstring, jstring); 

/* 
* Class:  CameraCatcher 
* Method: snapPic 
* Signature: (JLjava/lang/String;I)I 
*/ 
JNIEXPORT jint JNICALL Java_CameraCatcher_snapPic 
    (JNIEnv *, jobject, jlong, jstring, jint); 

#ifdef __cplusplus 
} 
#endif 
#endif 

C++コード:

JNIEXPORT jlong JNICALL Java_CameraCatcher_initCamera 
(JNIEnv * env, jobject c, jstring arg_ip, jstring arg_port, jstring arg_username, jstring arg_pwd) 
{ 
    return 1; 
} 
JNIEXPORT jint JNICALL Java_CameraCatcher_snapPic 
(JNIEnv * env, jobject c, jlong arg_id, jstring arg_path, jint arg_no) 
{ 
    return 2; 
} 

私はこのコードをコンパイルして、新しいDLLを入手します。 Yes.It作品:それはまだ2更新

.......以前のようにエラーが発生しましたが 。なぜ私の.cppファイルで関数定義コードが変更されたのか分かりません。私はEJPが昨日問題を教えてくれたのでjclassをjobjectに変更しました。昨日以来偶然に変更されていて、私は観察しなかったかもしれません。それは私の不注意です。もう一度皆様に感謝します。

EJPが言ったことはまさに問題です。私は静的関数を使ってファイルを生成しましたが、非静的な方法で動作させました。別の問題は、クラスTestを使用しているときにクラスCameraCatcherを生成したことです。

+0

javahファイルを生成したので、メソッドを 'static'から変更しました。 – EJP

+0

@EJPまだ分かりません。もっと詳しく説明できますか?私は何をすべきか? – lionel

+0

エラーが発生しました.hファイルを再生成しますか?それに応じてメソッドシグネチャを調整しますか? – EJP

答えて

1

私はあなたのコードをテストしました。あなたは機能を編集する必要がありますが

このような
#include "test.h" 
    #include <jni.h> 

JNIEXPORT jlong JNICALL Java_CameraCatcher_Test_initCamera 
    (JNIEnv *env, jobject obj, jstring ip, jstring port, jstring username, jstring pwd){ 

    return 1.0; 
} 
JNIEXPORT jint JNICALL Java_CameraCatcher_Test_snapPic 
    (JNIEnv *env, jobject obj, jlong id, jstring savePath, jint no){ 
    return 5; 
} 

何かを持っている必要があり、C++での名前はJava_CameraCatcher_Test_snapPicでそれを追加するには、クラスのテストの名前を忘れてはいけません。

編集1: これは私がヘッダーに持っているものです。

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

#ifndef _Included_CameraCatcher 
#define _Included_CameraCatcher 
#ifdef __cplusplus 
extern "C" { 
#endif 
/* 
* Class:  CameraCatcher 
* Method: initCamera 
* Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)J 
*/ 
JNIEXPORT jlong JNICALL Java_CameraCatcher_initCamera 
    (JNIEnv *, jobject, jstring, jstring, jstring, jstring); 

/* 
* Class:  CameraCatcher 
* Method: snapPic 
* Signature: (JLjava/lang/String;I)I 
*/ 
JNIEXPORT jint JNICALL Java_CameraCatcher_snapPic 
    (JNIEnv *, jobject, jlong, jstring, jint); 

#ifdef __cplusplus 
} 
#endif 
#endif 

C++:

#include "cameracatcher.h" 
#include <jni.h> 
#include <stdio.h> 
#include <iostream> 
#include <unistd.h> 
JNIEXPORT jlong JNICALL Java_CameraCatcher_initCamera 
    (JNIEnv *env, jobject obj, jstring ip, jstring port, jstring username, jstring pwd){ 

    return 1.0; 
} 
JNIEXPORT jint JNICALL Java_CameraCatcher_snapPic 
    (JNIEnv *env, jobject obj, jlong id, jstring savePath, jint no){ 
    return 5.5; 
} 

のJava:

public class CameraCatcher { 

    public native long initCamera(String ip, String port, String username, String pwd); 

    public native int snapPic(long id, String savePath, int no); 

    static { 
     System.load("/home/tarik/NetBeansProjects/Testc++/dist/test.so"); 
    } 

    public static void main(String[] args) { 
     // TODO Auto-generated method stub 
     CameraCatcher tNative = new CameraCatcher(); 
     String ip = "192.108.1.108"; 
     String port = "37777"; 
     String username = "admin"; 
     String pwd = "123456"; 
     long cameraId = tNative.initCamera(ip, port, username, pwd); 
     System.out.println(cameraId); 
     String savePath = "D:/"; 
     int number = tNative.snapPic(cameraId, savePath, 0); 
     System.out.println(number); 
    } 
} 

すべてが正常に動作します。

+0

CameraCatcherは私のクラス名です。私はデフォルトのパッケージを使用します。 – lionel

+1

こちらのコードではそうではありません。 ヘッダーを再生成し、同じメソッド名とそのパラメーターを使用することをお勧めします。 –

0

メソッド名は、規約に従う必要があります。 メソッド名は、JDKに付属の組み込みツールを使用して生成できます。

詳細については、このリンクをご覧ください。 https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html

+0

メソッド名は自動的に生成されます。変更はありません。 – lionel

+0

しかし、生成されたソースコードを変更しました。 – EJP

+0

@EJP私はソースコードの主な機能の内容を記入するだけです。これは、それが生成する.hファイルのために何の違いもありません。今、私は上記のJavaコードと同じコードを使用してヘッダファイルを生成しました。しかし、それはまだ動作しません。たぶん私はあなたのポイントが何であるか理解していません。 – lionel

1

ネイティブメソッドを含むJavaクラスは、という名前のテストです。しかし、あなたはCameraCatcherという名前のクラスのC++ヘッダーを生成しました(デフォルトパッケージ)。

Javaクラスの名前を変更するか、C++関数をJava_Test_initCameraおよびJava_Test_snapPicに変更することができます。これらの関数をextern "C"と定義することを忘れないでください(ヘッダファイルでは通常javahによって生成されます)。

関連する問題