在 JNI 中传递对象总是返回 NULL

Posted

技术标签:

【中文标题】在 JNI 中传递对象总是返回 NULL【英文标题】:Passing an object in JNI always returns NULL 【发布时间】:2013-06-04 07:46:52 【问题描述】:

我正在使用 JNI 将对象从 C++ 传递到 Java。但是我卡在代码中的某个地方 “GetMethodID”总是返回 NULL 并崩溃!下面是我使用的头文件和后面的cpp代码。

我的意图是从 JNI 返回一个对象,我总是在哪里得到 以下cpp代码中的“emu_response_constructor Null”。

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_em_Grabber */

#ifndef _Included_com_em_Grabber
#define _Included_com_em_Grabber
#ifdef __cplusplus
extern "C" 
#endif
/*
 * Class:     com_em_Grabber
 * Method:    getProcessedImage
 * Signature: (II[B)Lcom/em/Response;
 */
JNIEXPORT jobject JNICALL Java_com_em_Grabber_getProcessedImage
  (JNIEnv *, jobject, jint, jint, jbyteArray);

#ifdef __cplusplus

#endif
#endif

下面是我使用的cpp文件。对象传递给 Java 的位置。

JNIEXPORT jobject JNICALL Java_com_em_Grabber_getProcessedImage
  ( JNIEnv *env, jobject obj, jint jRows, jint jCols,jbyteArray jByteArray )

         jclass emu_response = env->FindClass("com/em/Response");

         if (emu_response == NULL) 
             cout << "emu_response Null" << endl;
        

         jmethodID emu_response_constructor = env -> GetMethodID(emu_response, "<init>", "(II[B)Lcom/em/Response;");
         if (NULL == emu_response_constructor ) 

             cout << "emu_response_constructor Null" << endl;

         
   int number = 90;
   jobject jEmuResponse = env->NewObject ( emu_response,emu_response_constructor, jByteArray, number );

 return jEmuResponse;


下面是我的java类:

public class Response 


    private int age;
    private byte[] result = null;


    public Response()
    

    
    public Response(byte[] result,int age) 
    this.age = age;
    this.result = result;
    

    public int getAge() 
    return age;
    
    public void setAge(int age) 
    this.age = age;
    
    public byte[] getResult() 
    return result;
    
    public void setResult(byte[] result) 
    this.result = result;
    

【问题讨论】:

你能添加你的Java类吗? @ZagorulkinDmitry 我已经用 Java 类更新了我的帖子。 请同时显示native 方法Grabber.getProcessedImage()。可能是声明问题。 【参考方案1】:

不要尝试自己编造 JNI 签名。使用 javap -s 的输出。

在这种情况下,很明显你的参数类型是乱序的。 我认为正确的签名是“([BI)Lcom/em/Response;”,但不要相信我的话:使用 javap -s.总是。

并修复您的代码,这样如果您确实从任何 API 获得了意外结果,您就不会只是打印它并继续,就好像该值是合法的一样。这就是导致坠机的原因。

【讨论】:

@downvoter 请解释为什么您不应该使用 javap -s 来获得字母完美的 JNI 方法签名,和/或为什么您不应该检查 JNI API 调用的结果。

以上是关于在 JNI 中传递对象总是返回 NULL的主要内容,如果未能解决你的问题,请参考以下文章

使用 JNI 传递和返回 OpenCv Mat 对象

Android JNI 传递对象

为啥坐标对象的标题属性在移动 safari 中总是返回 null?

混合编程jni 第九篇之Jni总结

java 通过jni 向 c 传递一个 java 对象, c 如何取得这个对象的属性值?

spring mvc 处理pojo传递对象时该对象继承父类的属性在网络接收端接收该属性值总是null,why?