Сначала я заранее прошу прощения за возможные ошибки на английском языке. Я пытаюсь использовать JNI для вызова функции C ++ / OpenCV (для возврата гистограммы) из моего Java-приложения, которое использует Processing (я работаю с Kinect для распознавания жестов и хочу вызвать код C ++ для сравнения некоторых гистограмм в реальном время). Для этого я частично следовал этому туто:
ibm.com/developerworks/java/tutorials/j-jni/j-jni.html
Я использую Eclipse и Visual Studio 2010, Windows 8 64 бит, JDK 1.8 32 бит.
Таким образом, я создаю свой файл класса с помощью javac без проблем, но когда я пытался создать свой заголовочный файл с помощью javah, у меня появляется эта ошибка:
Error: cannot access processing.core.PApplet
class file for processing.core.PApplet not found
Обратите внимание, что моя Java-программа компилируется и работает правильно, если я не пытаюсь использовать мой инструмент javah (в этом случае он вылетает при попытке вызвать метод JNI)
Вот мои коды:
MyProcessingSketch.java
package v2;
//imports
public class MyProcessingSketch extends PApplet {
//various attributes
public native static void histo(String inFile, long addr);
static {
System.load("C:/Users/Richard/Documents/Visual Studio 2010/Projects/Test/Debug/Test.dll");
}
//various methods, among them setup() and draw()
public static Mat histogram(String inFile)
{
Mat m=new Mat();
histo(folder+inFile, m.getNativeObjAddr());
return m;
}
public static void main(String args[]) {
PApplet.main(new String[] { "--present", "v2.MyProcessingSketch" });
}
}
test.cpp
#include "c:/users/richard/workspace/Kinect/src/v2_MyProcessingSketch.h"
#include "opencv2/highgui/highgui.hpp"#include "opencv2/imgproc/imgproc.hpp"#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;JNIEXPORT void JNICALL Java_v2_MyProcessingSketch_histo (JNIEnv *env, jobject obj, jstring inFile, jlong addr) {
Mat base;
const char* str = env->GetStringUTFChars(inFile, 0);
base = imread(str, 1 );
/// Convert to HSV
cvtColor( base, base, COLOR_BGR2HSV );
/// Using 50 bins for hue and 60 for saturation
int h_bins = 50; int s_bins = 60;
int histSize[] = { h_bins, s_bins };
// hue varies from 0 to 179, saturation from 0 to 255
float h_ranges[] = { 0, 180 };
float s_ranges[] = { 0, 256 };
const float* ranges[] = { h_ranges, s_ranges };
// Use the o-th and 1-st channels
int channels[] = { 0, 1 };
/// Histograms
Mat hist;
/// Calculate the histograms for the HSV images
calcHist( &base, 1, channels, Mat(), hist, 2, histSize, ranges, true, false );
normalize( hist, hist, 0, 1, NORM_MINMAX, -1, Mat() );
Mat* mat=(Mat*) addr;
mat->create(hist.rows, hist.cols, hist.type());
memcpy(mat->data, (&hist)->data, mat->step * mat->rows);
}int main(){return 0;}
Мои инструменты Eclipse
Инструмент Javac: http://hpics.li/4c612ea
Инструмент Javah + проводник моего проекта: http://hpics.li/1054ea2
Обратите внимание, что все работает в случае одного и того же кода C ++ (просто путем замены имени и включения) и другого кода Java без части обработки, например:
Test.java
package v2;
//imports
public class Test {
public native static void histo(String inFile, long addr);
static {
System.load("C:/Users/Richard/Documents/Visual Studio 2010/Projects/Test/Debug/Test.dll");
}
public static void main(String[] args)
{
Mat m = new Mat();
Mat m2 = new Mat();
histo(folder+"front.jpg", m.getNativeObjAddr());
histo(folder+"up.jpg", m2.getNativeObjAddr());
System.out.println(Imgproc.compareHist(m, m2, Imgproc.CV_COMP_BHATTACHARYYA));
}
}
Заранее спасибо !
РЕДАКТИРОВАТЬ :
Я не знаю почему (и это очень раздражает), но, наконец, Джава построил мои заголовочные файлы:
v2_MyProcessingSketch.h
**/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class v2_MyProcessingSketch */
#ifndef _Included_v2_MyProcessingSketch
#define _Included_v2_MyProcessingSketch
#ifdef __cplusplus
extern "C" {
#endif
#undef v2_MyProcessingSketch_serialVersionUID
#define v2_MyProcessingSketch_serialVersionUID 1i64
/*
* Class: v2_MyProcessingSketch
* Method: histo
* Signature: (Ljava/lang/String;J)V
*/
JNIEXPORT void JNICALL Java_v2_MyProcessingSketch_histo
(JNIEnv *, jclass, jstring, jlong);
#ifdef __cplusplus
}
#endif
#endif
v2_MyProcessingSketch_DisposeHandler.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class v2_MyProcessingSketch_DisposeHandler */
#ifndef _Included_v2_MyProcessingSketch_DisposeHandler
#define _Included_v2_MyProcessingSketch_DisposeHandler
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif
Но когда моя программа вызывает нативную функцию, у меня появляется новая ошибка:
Exception in thread "Animation Thread" java.lang.UnsatisfiedLinkError:v2.MyProcessingSketch.histo(Ljava/lang/String;J)V
Задача ещё не решена.