在JNI上下文中使用org.bytedeco.javacpp对象

时间:2018-07-25 13:22:40

标签: java c++ kotlin java-native-interface javacpp

我目前正在编写JNI加速器库,以替换某些系统(Linux x64和macOS)上的Java方法。

我有一个用JavaCV 3.4.2用Kotlin / Java编写的工作代码

我创建了一个JNI库,该库执行相同的工作,以避免JVM和JNI之间来回多次。

示例:

没有加速的Kotlin端(JVM + JavaCV):

override fun process(image: Mat): FeaturesDetectorResult {
    val faceDetection = Dlib.faceDetection(image)
    ...
}

JNI加速器部分:

科特琳

@ByVal
protected external fun Process(imagePtr: Long, lines: List<opencv_core.Rect>): opencv_core.Mat?;

// method of class overriding the native method
override fun process(image: opencv_core.Mat): FeaturesDetectorResult {
    val lines = ArrayList<opencv_core.Rect>()
    val rotatedMat = Process(image.address(), lines)
    return FeaturesDetectorResult(rotatedMat, lines)
}

C ++

JNIEXPORT jlong JNICALL Java_fr_tessi_bmd_image_accel_MserFeaturesDetectorNative_Process
  (JNIEnv *env, jobject self, jlong imagePtr, jobject list) {

在我的C ++方法结束时,我陷入了将本地cv::Mat转换为其Java副本opencv_core.Mat(不存在具有本地地址的构造函数)的麻烦。

我查看了javacpp生成的源,似乎将本机对象视为jlong。我所有的测试都导致崩溃。

任何人都知道如何使用自制的JNI库来回传递org.bytedeco.javacpp对象吗?

编辑:

我发现了一种从opencv_mat.Mat创建cv::Mat的解决方法:

//Safety checks removed for simplicity
#define ptr_to_jlong(a) ((jlong)(uintptr_t)(a))
Mat* toReturnToJava;
jclass pointerClass = env->FindClass("org/bytedeco/javacpp/Pointer"); 
jfieldID addressFld = env->GetFieldID(pointerClass, "address", "J");
jobject pointerObj = env->AllocObject(pointerClass);
env->SetLongField(pointerObj, addressFld, ptr_to_jlong(toReturnToJava));

Mat作为jlong返回Java,而Java端将返回值声明为opencv.Mat

相同类型的代码似乎不适用于Rect(我改用了构造函数Rect(x,y,w,h))。

0 个答案:

没有答案