首页 > 解决方案 > JNI - Java 应用程序的 C++ 变量值

问题描述

所以我有这个 JNI 函数,它给了我一些 x 和 y 值。我想将值发送到 java 应用程序,但由于它是一个 JNICall,我不知道该怎么做?

JNIEXPORT void JNICALL Java_com_example_foo(JNIEnv env*, jclass FooClass, jlong matRgba,) {
    Mat& rgba = *(Mat*)matRgba;
  jmethodID mid_getCoord = env->GetStaticMethodID(FooClass, "getCoord", "(II)V");

    detect(rgba);
}

void detect(Mat& frame){
  String eye_cascade_name = "test.eyes.cascade.xml";

CascadeClassifier eyes_cascade;
std::vector<Rect> eyes;
Mat frame_gray;


for (size_t i = 0; i < eyes.size(); i++){
    Point center(eyes[i].x + eyes[i].width*0.5, eyes[i].y + eyes[i].height*0.5);

  env->CallStaticVoidMethod(FooClass, mid_getCoord, eyes[i].x, eyes[i].y);


    ellipse(frame, center, Size(eyes[i].width*0.5, eyes[i].height*0.5));

    Mat eyesROI = frame_gray(eyes[i]);
}

}

去做; 将这两个值(x 和 y)发送到 Java 应用程序?*请注意,这些值会不断变化。

到目前为止我所想到的。是否将 x 和 y 创建为全局值并将它们设置为 eye[i].x 和 y 并以某种方式将它们发送到应用程序。我不确定这是否是正确的方法,我已经尝试过尝试不同但失败.. 有多个 NDK 错误并没有真正告诉我出了什么问题.. 所以我基本上坚持如何解决这个问题..

任何帮助表示赞赏!

Java类;

public class FooClass {
public native static void eyeDetection(long matRgba);
static void getCoord(int x, int y) {
    System.out.println("got coordinates: " + x + ", " + y);
}

我可能在这里做错了,但是如何将这些值返回给 java 应用程序

检测方法工作得很好..它是一些opencv的东西,它应该在眼睛上画一个椭圆..我只需要传递eyes[i].x和eyes[i].y的坐标

标签: javaandroidc++java-native-interface

解决方案


要从本机代码中获取结果,您可以在 Java 中定义回调方法。

package com.example.foo;
public class Foo {
    public native static void eyeDetection(long addrRgba);
    static void getCoord(int x, int y) {
      System.out.println("got coordinates: " + x + ", " + y);
      // consume the coordinates in Java, e.g.
      Foo2.onCreate(x, y);
    }
}

 

JNIEXPORT void JNICALL Java_com_example_foo_Foo_eyeDetection(JNIEnv *env, jclass FooClass, jlong matRgba) {
  Mat& rgba = *(Mat*)matRgba;
  jmethodID mid_getCoord = env->GetStaticMethodID(FooClass, "getCoord", "(II)V");
   String eye_cascade_name = "test.eyes.cascade.xml";

  CascadeClassifier eyes_cascade;
  std::vector<Rect> eyes;
  eyes_cascade.detectMultiScale(…);
  for (size_t i = 0; i < eyes.size(); i++) {
    env->CallStaticVoidMethod(FooClass, mid_getCoord, eyes[i].x, eyes[i].y);
    …
  }
}

请注意,如果您不想在用于调用eyeDetection()的线程上执行回调,则必须将该线程附加到 JVM(获取不同的线程相关 JNIEnv 指针),并保留对FooClass的全局引用。


推荐阅读