JNI java.lang.UnsatifiedLinkError,无法链接方法
我看到了很多关于不满意链接错误的问题,我知道我的问题是什么。我明白了 线程“main”java.lang.unsatifiedlinkerror:Test.initCamera(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)J中出现异常 这意味着dll已加载,但找不到方法。但是,我检查了我的源代码和java代码。方法名和参数都是正确的。我不知道我的代码出了什么问题 这是我的密码 爪哇: C++: 这真让我发疯 更新1: 谢谢大家的回复。正如@Mr Tarik所示,我已经更改了代码 爪哇: 然后我使用javah生成头文件:JNI java.lang.UnsatifiedLinkError,无法链接方法,java,c++,java-native-interface,Java,C++,Java Native Interface,我看到了很多关于不满意链接错误的问题,我知道我的问题是什么。我明白了 线程“main”java.lang.unsatifiedlinkerror:Test.initCamera(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)J中出现异常 这意味着dll已加载,但找不到方法。但是,我检查了我的源代码和java代码。方法名和参数都是正确的。我不知道我的代码出了什么问题 这是我的密码 爪哇: C++:
#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
我编译这段代码并获得新的dll。
但是它仍然像以前一样有错误
更新2:
是的,很有效。我不知道为什么我的.cpp文件中的函数定义代码发生了更改。正如EJP昨天告诉我的那样,我只是把jclass改成了jobject。可能是因为昨天的一次偶然的改变,我没有观察到。都是我的粗心。再次感谢大家
问题正是EJP所说的。我使用静态函数生成文件,但使其以非静态方式工作。另一个问题是,我在使用类测试时生成了类CameraCatcher。JNI方法名称需要遵循约定。 方法名可以使用JDK附带的内置工具生成 有关更多详细信息,请参阅此链接。
我测试了你的代码。你需要在C++中编辑函数名称,你需要有这样的东西
#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类名为Test。但是您生成了C++类的标题,该类名为<强> CMACALATCHER < /St>(默认包)。
您可以重命名Java类,或者将C++函数改为<代码> javathTestOnItPrime< /C>和<代码> javajava TestPosiSnAPIC。不要忘记将这些函数定义为
extern“C”
(我们通常在头文件中这样做,由javah生成)。自从生成javah
文件以来,您已将方法从静态更改为。@EJP我仍然不清楚。你能更详细地解释一下吗?我应该怎么做?呃,重新生成.h文件?并相应地调整您的方法签名?叹气。在.h文件中有Java\u CameraCatcher\u initCamera
,在.cpp文件中有initCamera
。这些仍然不一致。类似地,snapPic
。方法名是自动生成的。我没有更改它。但是您更改了生成它的源代码。@EJP我只是填写源代码的main函数的内容。这对它生成的.h文件没有任何影响。但它仍然不起作用。也许我不明白你的意思。静态JNI函数的第二个参数是jclass
。非静态的hasjobject
。您的C++代码有<代码> jCys<代码>,但是您的java代码没有<代码>静态<代码>。当您运行javah
时,您有static
,随后您将其删除。或C++代码从不同意生成的.h文件。@ EJP谢谢您的解释。我现在明白你的意思了。但是,我尝试使用非静态函数并重新生成dll。它仍然有这个问题。CameraCatcher是我的类名。我使用默认的包。这里的代码不是这样的。我建议您重新生成标头,并使用相同的方法名称及其参数。
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);
}
}
#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
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;
}
#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;
}
/* 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
#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;
}
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);
}
}