【问题标题】:JNI doesn't initialize Class Obj with StringJNI 不使用 String 初始化 Class Obj
【发布时间】:2015-09-01 21:40:46
【问题描述】:

下面是我的 C 和 Java 代码。 Java 调用function1 来收集Stringinteger 并使用ResultCollector 对象返回它们。 ResultCollector 是一个外部类,换句话说,它没有嵌套在ResultCollecter 类中。此外,它具有三个构造函数。我还有其他函数可以使用带有(IF)V 签名的构造函数。此外,第三个构造函数也不能正常工作(即(II)V)。

Java 代码是:

package user.directory;
public class ResultCollector {
    private int err;
    private float resVal;
    private String resID;

/**
 * Signature (IF)V
 */
public ResultCollector(int err, float value) {
    this.err = err;

    this.resVal = value;
}

/**
 * Signature (II)V
 */
public ResultCollector(int err, int value) {
    this.err = err;

    this.resVal = (float) value;
}

/**
 * Signature (ILjava/lang/;)V
 */
public ResultCollector(int err, char[] id) {
    this.err = err;
    this.resID = String.copyValueOf(id);

}

public String id() {
    return resID;
}

public int err() {
    return err;
}

public float value() {
    return resVal;
}

public void setParam(int err, String id, float value) {
    this.err = err;
    this.resID = id;
    this.resVal = value;
}

}

而C代码是:

JNIEXPORT jobject JNICALL Java_project_function1(
        JNIEnv *env, jobject obj, jint index) {
    jint t;
    char *id = C function to return string; 
    t = an error that is needed;


     if (c == NULL)
         // throw exception
       return NULL;

     jstring name = (*env)->NewStringUTF(env, id);

     if (name == NULL)
         // throw exception
       return NULL;

     jclass c = (*env)->FindClass(env,
        "user/directory/ResultCollector");
     jmethodID constr = (*env)->GetMethodID(env, c, "<init>", "(ILjava/lang/String;)V");

    if (constr == NULL)
    //cannot get the constructor correctly
       return NULL;

   jobject result = (*env)->NewObject(env, c, constr, t, name);
   return result;
}

我的问题是:如何初始化外部类?这段代码哪里出错了?

【问题讨论】:

    标签: string object constructor java-native-interface


    【解决方案1】:

    char[]String 不同。构造函数的签名应该是(I[C)V[ 表示数组,C 表示字符):

    jmethodID constr = (*env)->GetMethodID(env, c, "<init>", "(I[C)V");
    

    您还需要传递 jcharArray 而不是 jstring。您可以像这样创建jcharArray

    int len = strlen(id);
    jcharArray charArray = (*env)->NewCharArray(env, len);
    (*env)->SetCharArrayRegion(env, charArray, 0, len, id);
    

    或者,您可以更改 Java 代码以接受 String 而不是 char[]

    public ResultCollector(int err, String id) {
        this.err = err;
        this.resID = id;    
    }
    

    【讨论】:

    • 道德:不要自己编写 JNI 方法签名。使用javap -s 的输出。永远不会错。
    • 谢谢 samgak!尝试了不同的方法。我也试过arraychar。您的方法对我不起作用,即使我不得不承认您的答案是完全正确的!问题是 JNI 一次只能识别一个构造函数。所以,我最终为每个结果定义了三个类。现在,它正在工作。我不知道为什么 JNI 对几个构造函数不满意。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-14
    • 1970-01-01
    相关资源
    最近更新 更多