【问题标题】:How to pass a ArrayList<Point> for a jni C++ function?如何为 jni C++ 函数传递 ArrayList<Point>?
【发布时间】:2015-11-06 22:24:29
【问题描述】:

我正在使用 Android jni C++ 用 Ja​​va 做一个项目。我在 C++ 中有一个带有以下参数的函数:

C++ 函数: void rectify (vector &lt;Point2f&gt; &amp; corners, Mat &amp; img) {...}

在 JAVA 中,调用将是:

Mat image = Highgui.imread("img.png");
List <MatOfPoint> cornners =  new ArrayList<MatOfPoint>();;
Point b = new Point (real_x2, real_y2);
MatOfPoint ma = new MatOfPoint (b);
cornners.add(ma);
rectfy(image.getNativeObjAddr(), cornners)

public native void rectfy(long mat, "??" matofpoint);

有了这个,我想知道函数C++ jni如何:

JNIEXPORT void JNICALL Java_ImageProcessingActivity_rectfy (JNIEnv * jobject, ?? cornners, inputMatAddress jlong)

【问题讨论】:

  • 您是否尝试过在 Java 端创建具有所需接口的 Java 本机方法,并使用 javah 创建 C 端标头?
  • 我在 Eclipse 中使用 NDK。我有一个.java,它有一个本地方法的声明,引用一个.cpp,它加载了System.loadLibrary ("rectifylib"),“rectifylib” 指向jni-parts.cpp它在文件夹和 jni 里面,它有 JNICALL Java_ImageProcessingActivity_rectfy (...)_. 的方法
  • 你想知道函数what会怎样?问题是什么?您在寻找关键字void吗?
  • 我想知道的是如何将ArrayList &lt;MatOfPoint2f&gt; (vector &lt;Point2f&gt;) java 传递给 C++ jni 中的代码。 C++ 中的函数将接收的参数类型是什么?
  • 据我了解,在 JNI 中,所有类(非基元)都以jobject 传递。以类似的方式,当您想从 C++ 传回 Java 类时,您返回一个 jobject,它已被实例化为例如 ArrayList。我认为您可以找到几个比我更好地解释这一点的 JNI 示例/教程。

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


【解决方案1】:

如果我对您的理解正确,您想要做的是将一堆点从 Java 传递到 C++,那么我认为这大致就是您要寻找的:

#include <vector>
#include <jni.h>

class Point2f {
public:
    double x;
    double y;
    Point2f(double x, double y) : x(x), y(y) {}
};

extern "C" JNIEXPORT void JNICALL Java_com_example_ImageProcessingActivity_transferPointsToNative(JNIEnv* env, jobject self, jobject input) {
    jclass alCls = env->FindClass("java/util/ArrayList");
    jclass ptCls = env->FindClass("java/awt/Point");

    if (alCls == nullptr || ptCls == nullptr) {
        return;
    }

    jmethodID alGetId  = env->GetMethodID(alCls, "get", "(I)Ljava/lang/Object;");
    jmethodID alSizeId = env->GetMethodID(alCls, "size", "()I");
    jmethodID ptGetXId = env->GetMethodID(ptCls, "getX", "()D");
    jmethodID ptGetYId = env->GetMethodID(ptCls, "getY", "()D");

    if (alGetId == nullptr || alSizeId == nullptr || ptGetXId == nullptr || ptGetYId == nullptr) {
        env->DeleteLocalRef(alCls);
        env->DeleteLocalRef(ptCls);
        return;
    }

    int pointCount = static_cast<int>(env->CallIntMethod(input, alSizeId));

    if (pointCount < 1) {
        env->DeleteLocalRef(alCls);
        env->DeleteLocalRef(ptCls);
        return;
    }

    std::vector<Point2f> points;
    points.reserve(pointCount);
    double x, y;

    for (int i = 0; i < pointCount; ++i) {
        jobject point = env->CallObjectMethod(input, alGetId, i);
        x = static_cast<double>(env->CallDoubleMethod(point, ptGetXId));
        y = static_cast<double>(env->CallDoubleMethod(point, ptGetYId));
        env->DeleteLocalRef(point);

        points.push_back(Point2f(x, y));
    }

    env->DeleteLocalRef(alCls);
    env->DeleteLocalRef(ptCls);
}

在Java中有相应的方法声明:

private native void transferPointsToNative(ArrayList<Point> input);

【讨论】:

  • 为了后代/记录,在从 Java_com_example_ImageProcessingActivity_transferPointsToNative 和 env-&gt;DeleteLocalRef(point) 返回之前,您需要在循环中使用 env-&gt;DeleteLocalRef(alCls 和 ptCls) 以避免内存泄漏。
猜你喜欢
  • 2019-06-21
  • 1970-01-01
  • 2020-02-14
  • 2021-07-22
  • 2012-01-22
  • 1970-01-01
  • 2014-07-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多