我在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.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();
}
}
.h代码:
/* 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
TEST.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;
}
我在网上搜索了很长时间。但我无法解决我的问题。请帮忙或尝试给我一些想法。
答案 0 :(得分:0)
您声明了此功能:
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代码中。
答案 1 :(得分:0)
.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
方法声明它们:
public native void helloworld(String[] args);
结果签名将是:
JNIEXPORT void JNICALL Java_Main_helloworld(JNIEnv *, jobject, jobjectArray);
但是此String[]
未转换为argc
和argv
,您必须使用JNI api手动执行此操作:
#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
}