将Mat传递给JNI函数 - OpenCV

时间:2015-02-11 00:50:45

标签: android c++ opencv android-ndk java-native-interface

我尝试使用Mat通过JNI函数传递jlong对象,但我在运行时遇到此异常:

(__gnu_cxx::__verbose_terminate_handler()+276)
(__cxxabiv1::__terminate(void (*)())+8)
(std::terminate()+20)
(__cxa_throw+148)
(cv::error(cv::Exception const&)+80)
(cv::Mat::copySize(cv::Mat const&)+18)
(cv::Mat::Mat(cv::Mat const&)+122)
(cv::_InputArray::getMat(int) const+252)
(cv::split(cv::_InputArray const&, cv::_OutputArray const&)+20)
(cv::split(cv::Mat const&, std::vector<cv::Mat, std::allocator<cv::Mat> >&)+28)
(cv::xphoto::balanceWhite(cv::Mat const&, cv::Mat&, int, float, float, float, float)+54)
(Java_com_myapp_camera_CameraManager_simpleWhiteBalance+18)

本机函数定义如下

public native static void simpleWhiteBalance(Mat source, Mat dest);

并按以下方式实施

#include <jni.h>
#include <opencv2/core/core.hpp>
#include "opencv2/xphoto.hpp"
#include "simple_color_balance.cpp"
#include "com_myapp_camera_CameraManager.h"

JNIEXPORT void JNICALL Java_com_myapp_camera_CameraManager_simpleWhiteBalance
  (JNIEnv *, jclass, jlong in, jlong out) {

     cv::Mat& inMat = *(cv::Mat*)in;
     cv::Mat& outMat = *(cv::Mat*)out;

    cv::xphoto::balanceWhite(inMat, outMat, cv::xphoto::WHITE_BALANCE_SIMPLE);
}

我是C ++的新手,这个例外意味着什么?

2 个答案:

答案 0 :(得分:1)

jlong未映射对象,但long(对象映射为jobject),Mat的Java实例与cv::Mat的实例完全不同并且不能以这种方式铸造。这里通常的方法是使用Java中的long作为C ++中指针的近似值,并按照您使用的方式进行投射。

此外,这不是例外,而是由未捕获的异常引起的崩溃。要获得异常,您需要在C ++代码中使用try-catch。 C ++异常与Java异常不兼容,所以你不能抛出C ++并用Java捕获它,反之亦然。

答案 1 :(得分:-1)

cv::Mat *inMat = (cv::Mat*)in;
cv::Mat *outMat = (cv::Mat*)out;

请传递指针而不是引用。见example