“线程中的期望”;“主要”;java.lang.UnsatifiedLinkError:JNItest2.helloworld()V
我在ubuntu的test.cpp中创建了libcc.so,并使用指令“线程中的期望”;“主要”;java.lang.UnsatifiedLinkError:JNItest2.helloworld()V,java,java-native-interface,Java,Java Native Interface,我在ubuntu的test.cpp中创建了libcc.so,并使用指令ldd检查它与opencv2.4.2、ffmpeg0.11.1和其他文件的链接是否没有问题 但是,当我尝试使用eclipse加载libcc.so时,出现了以下错误: Exception in thread "main" java.lang.UnsatisfiedLinkError: JNItest2.helloworld()V at JNItest2.helloworld(Native Method) at JNItest2.
ldd
检查它与opencv2.4.2、ffmpeg0.11.1和其他文件的链接是否没有问题
但是,当我尝试使用eclipse加载libcc.so时,出现了以下错误:
Exception in thread "main" java.lang.UnsatisfiedLinkError: JNItest2.helloworld()V
at JNItest2.helloworld(Native Method)
at JNItest2.main(JNItest2.java:28)
Java代码:
public class JNItest2 {
public native void helloworld();
static{
String libPath= "/home/sun/workspace/JNItest2/src";
System.setProperty("java.library.path",libPath);
String Path = System.getProperty("java.library.path");
System.out.println("java.library.path=" + Path);
System.loadLibrary("cc");
}
public static void main(String[] args){
new JNItest2().helloworld();
}
}
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JNItest2 */
#ifndef _Included_JNItest2
#define _Included_JNItest2
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: JNItest2
* Method: helloworld
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_JNItest2_helloworld
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
.h代码:
public class JNItest2 {
public native void helloworld();
static{
String libPath= "/home/sun/workspace/JNItest2/src";
System.setProperty("java.library.path",libPath);
String Path = System.getProperty("java.library.path");
System.out.println("java.library.path=" + Path);
System.loadLibrary("cc");
}
public static void main(String[] args){
new JNItest2().helloworld();
}
}
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JNItest2 */
#ifndef _Included_JNItest2
#define _Included_JNItest2
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: JNItest2
* Method: helloworld
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_JNItest2_helloworld
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
/*不要编辑此文件-它是机器生成的*/
#包括
/*类JNItest2的标头*/
#如果不包括
#定义包含的项目2
#ifdef_uucplusplus
外部“C”{
#恩迪夫
/*
*类别:JNItest2
*方法:helloworld
*签字:()五
*/
JNIEXPORT void JNICALL Java\u JNItest2\u helloworld
(JNIEnv*,jobject);
#ifdef_uucplusplus
}
#恩迪夫
#恩迪夫
测试.cpp
#include <jni.h>
#include "JNItest2.h"
#include <stdio.h>
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <ctype.h>
#include <unistd.h>
#include <signal.h>
#include <algorithm>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <fstream>
#include <iostream>
#include <vector>
#include <list>
#include <string>
IplImage* image = 0;
IplImage* prev_image = 0;
CvCapture* capture = 0;
JNIEXPORT void JNICALL
Java_JNItest2_helloworld(JNIEnv *env,jobject object,int argc,char ** argv)
{
signal(SIGSEGV,sighandler);
int frameNum = 0;
char* video=null;
char* video = argv[1];
capture = cvCreateFileCapture(video);
if( !capture ) {
printf( "Could not initialize capturing..\n" );
return ;
}
while(true)
{
frameNum += 1;
IplImage* frame = 0;
int i, j, c;
frame = cvQueryFrame( capture );
if( !frame )
break;
if( !image ) {
image = cvCreateImage( cvSize(frame->width,frame->height), 8, 3);
image->origin = frame->origin;
}
cvCopy( frame, image, 0 );
std::cerr << "The " << frameNum << "-th frame" << std::endl;
frameNum++;
}
return;
}
#包括
#包括“JNItest2.h”
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
IplImage*image=0;
IplImage*prev_image=0;
CvCapture*capture=0;
JNIEXPORT void JNICALL
Java_JNItest2_helloworld(JNIEnv*env,jobject对象,int argc,char**argv)
{
信号(SIGSEGV、sighandler);
int frameNum=0;
char*video=null;
char*video=argv[1];
capture=cvCreateFileCapture(视频);
如果(!捕获){
printf(“无法初始化捕获..\n”);
返回;
}
while(true)
{
frameNum+=1;
IplImage*frame=0;
int i,j,c;
帧=cvQueryFrame(捕获);
如果(!帧)
打破
如果(!图像){
image=cvCreateImage(cvSize(帧->宽度,帧->高度),8,3);
图像->原点=帧->原点;
}
cvCopy(帧,图像,0);
std::cerr您已声明此函数:
JNIEXPORT void JNICALL Java_JNItest2_helloworld
(JNIEnv *, jobject);
但你要实现这一点:
JNIEXPORT void JNICALL
Java_JNItest2_helloworld(JNIEnv *env,jobject object,int argc,char ** argv)
确保有:
JNIEXPORT void JNICALL
Java_JNItest2_helloworld(JNIEnv *env,jobject object)
在您的cpp代码中。您的.h
文件中的签名与.cpp
文件中的签名不匹配
JNIEXPORT void JNICALL Java_JNItest2_helloworld(JNIEnv *, jobject);
JNIEXPORT void JNICALL Java_JNItest2_helloworld(JNIEnv *env,jobject object,int argc,char ** argv)
您尝试调用的方法是头文件中的方法。但缺少实现
如果要将参数传递到C
端,则必须使用native
method声明它们:
public native void helloworld(String[] args);
由此产生的签名将是:
JNIEXPORT void JNICALL Java_Main_helloworld(JNIEnv *, jobject, jobjectArray);
但是此字符串[]
未转换为argc
和argv
,您必须使用手动执行此操作:
#include <stdio.h>
#include <stdlib.h>
JNIEXPORT void JNICALL Java_Main_helloworld(JNIEnv *env, jobject o, jobjectArray args) {
int argc = (*env)->GetArrayLength(env, args);
const char* argv[argc];
// convert String[] to const char**
for(int i = 0; i < argc; i++) {
jstring string = (jstring) (*env)->GetObjectArrayElement(env, args, i);
int slength = (*env)->GetStringLength(env, string);
const wchar_t* wchars = (*env)->GetStringChars(env, string, NULL);
argv[i] = malloc(slength + 1); // + 1 for terminator
wcstombs(argv[i], wchars, slength + 1);
(*env)->ReleaseStringChars(env, string, wchars);
}
// use argc and argv
}
#包括
#包括
JNIEXPORT void JNICALL Java_Main_helloworld(JNIEnv*env,jobject o,jobjectArray args){
int argc=(*env)->GetArrayLength(env,args);
常量字符*argv[argc];
//将字符串[]转换为常量字符**
对于(int i=0;iGetObjectArrayElement(env,args,i);
int slength=(*env)->GetStringLength(env,string);
常量wchar_t*wchars=(*env)->GetStringChars(env,string,NULL);
argv[i]=malloc(长度+1);//+1表示终止符
wcstombs(argv[i],wchars,slength+1);
(*env)->ReleaseStringChars(env,string,wchars);
}
//使用argc和argv
}
Tank you!我已经尝试过了,但是遇到了另一个问题。问题是我可以在eclipse上运行,但是我不能通过runnablejar
文件在cmd上运行。错误消息是:线程“main”java.lang.UnsatisfiedLinkError中出现异常:java.library.path中没有测试,位于java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867)java.lang.Runtime.loadLibrary0(Runtime.java:870)和JNItest2(JNItest2.java:23)的java.lang.System.loadLibrary(System.java:1122)@彭思倩 如果您仍然使用Java硬编码的库的绝对路径,我不明白为什么它不起作用,除非您移动了库。我仍然使用Java设置了库的绝对路径,并且在同一台计算机上运行jar文件。此外,我在/home/sun/workspace/JNItest2/src/
文件中检查了库。但是,当我运行jar文件时错误消息仍然出现。另外,我使用了指令java-jar./test5.jar./home/sun/iDT/video/video.avi
@彭思倩 我真的看不出答案。但这确实是一个不同的问题。如果你想在网站上问另一个问题,那么其他人也可以尝试。