4

我在Java中有这个类:

public class CameraActivity extends Activity {

  ...      

  public class RecognitionResult {
    public String text;
    public int x;
    public int y;
    public int width;
    public int height;

    public RecognitionResult(String text, int x, int y, int width, int height) {
      this.text = text;
      this.x = x;
      this.y = y;
      this.width = width;
      this.height = height;
    }
  }
}

这是我的 JNI 代码:

extern "C"
jobject Java_com_example_parkingcontrolsystem_CameraActivity_recognizeNumberPlate(JNIEnv *env,
                                                                                  jobject object,
                                                                                  jstring filename)
{
  jclass cls = env->FindClass("com/example/parkingcontrolsystem/CameraActivity$RecognitionResult");
  std::cout << "Class: " << cls << std::endl;

  jmethodID constructor = env->GetMethodID(cls, "<init>", "(Ljava/lang/String;IIII)V");
  std::cout << "Method: " << constructor << std::endl;

  recognition_result = env->NewObject(cls, constructor, "Hello from JNI", 0, 0, 50, 100);
  std::cout << "Object: " << recognition_result << std::endl;

  return recognition_result;
}

FindClass 返回不是 NULL,OK。但是 GetMethodID 总是返回零。我试图制作没有参数的默认构造函数,而不是使用“()V”签名,但GetMethodID返回NULL。

怎么了?

4

1 回答 1

3

如果使用 JNI 实例化内部类,则还必须在使用的签名中传递父类GetMethodId,以便接收有效的jmethodID.

假设B是一个内部类A并且有一个构造函数,比如:public B(int someint)下面的代码可以工作(jobj指向一个实例A):

jclass jclazz = env->FindClass("org/somepackage/A$B");
assert(jclazz != nullptr);
jmethodID mid = env->GetMethodID(jclazz, "<init>", "(Lorg/somepackage/A;I)V");
assert(mid != nullptr);
env->NewObject(jclazz, mid, jobj, 1);

操作问题的解决方案是:

 jclass cls = env->FindClass("com/example/parkingcontrolsystem/CameraActivity$RecognitionResult");
 std::cout << "Class: " << cls << std::endl;
 jmethodID constructor = env->GetMethodID(cls, "<init>","Lcom/example/parkingcontrolsystem/CameraActivity;Ljava/lang/String;IIII)V");
 std::cout << "Method: " << constructor << std::endl;
 recognition_result = env->NewObject(cls, constructor, object, "Hello from JNI", 0, 0, 50, 100);
 std::cout << "Object: " << recognition_result << std::endl;

注意:感谢 Selven,他在评论中也发布了相同的答案,但没有发布答案。

于 2015-01-25T15:17:31.140 回答