Reputation: 425
I have seen a lot of questions of UnsatisfiedLinkError and I know what my problem is. I get
Exception in thread "main" java.lang.UnsatisfiedLinkError: Test.initCamera(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)J
This means the dll has been loaded but it cannot find the method. However, I've checked my source code and java code. The method name and arguments are all right. I don't know what's wrong with my code.
Here are my codes.
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;
}
This really drives me crazy.
Update 1: Thanks for everyone's reply. I've changed my code just as @Mr Tarik showed.
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);
}
}
Then I use javah to generate header file:
#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++ code:
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;
}
I compile this code and get new dll. However it still has the error as before.......
Update 2: Yes.It works. I don't know why the function definition code changed in my .cpp file. I just changed the jclass to jobject as EJP told me the problem yesterday.Maybe it has been changed since yesterday by chance and I didn't observe. It's all my carelessness. Thanks for everyone again.
The problem is exactly what EJP said. I generated the file with static function but make it work in a non-static way. Another problem is that I generated the class CameraCatcher while I used the class Test.
Upvotes: 0
Views: 3538
Reputation: 449
I tested your code. you need to edit functions names in c++ you need to have something like this
#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;
}
dont forget the name of your class Test to add it in Java_CameraCatcher_Test_snapPic
.
edit 1: this is what i have in header:
/* 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);
}
}
All works fine.
Upvotes: 1
Reputation: 57173
The Java class that contains the native methods is named Test. But you generated the C++ header for class named CameraCatcher (in default package).
You can either rename the Java class, or change the C++ function to Java_Test_initCamera
and Java_Test_snapPic
. Don't forget to define these functions as extern "C"
(we usually do that in header file, generated by javah).
Upvotes: 1
Reputation: 951
THe JNI method names need to follow a convention. The method names can be generated using built-in tools that come with JDK.
Please see this link for more details. https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html
Upvotes: 0