有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

来自类变量的java JNI jstring?

我的Java类中有一个字符串变量:

public class myclass {
    protected final String file;
    myclass(String f) {
        file = f;
    }

    public native void processFiles();
    public static void main(String[] args) {
        myclass mc = new myclass(args[0]);
        mc.processFiles();
    }
}
在C++中,我有:

JNIEXPORT void JNICALL Java_myclass_processFiles(JNIEnv *env, jobject obj) {
    jclass baseClass = env->GetObjectClass(obj);
    jfieldID fid = env->GetFieldID(baseClass, "file", "Ljava/lang/String;");
    jchar filename = env->GetCharField(baseClass, fid);
    jstring fileFieldString = env->NewString(&filename, sizeof(filename));
    const char *nativeFileString = env->GetStringUTFChars(fileFieldString, NULL);
    printf("JNI: File path: %s\n", nativeFileString);
    env->ReleaseStringUTFChars(fileFieldString, nativeFileString);
}

我的输出是:

JNI: File path: ??2

我做错了什么,没有正确地将Java字符串转换为char*字符串?我提供路径~/Desktop/myfile作为唯一参数,因此args[0]中有一个值。我的想法是sizeof(filename)不正确,但从我的判断来看,没有其他选择

我确实尝试过:JNI. How to get jstring from jobject and convert it to char*但是当我将结果从GetObjectField()类型转换为jstring时,我得到一个错误:

# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00000001043111e8, pid=6191, tid=3591
#
# JRE version: Java(TM) SE Runtime Environment (8.0_45-b14) (build 1.8.0_45-b14)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.45-b02 mixed mode bsd-amd64 compressed oops)
# Problematic frame:
# V  [libjvm.dylib+0x3111e8]  jni_GetStringUTFChars+0x66
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again

此外,这只是OSX上的JNI和Java8,与Android无关

多谢各位

更新: 我能让一个朋友看一下,并让它与:

jfieldID fid = env->GetFieldID(baseClass, "file", "Ljava/lang/String;");
jstring jstr = (jstring) env->GetObjectField(thiz, fid);
const char *nativeFileString = env->GetStringUTFChars(jstr, NULL);
printf("JNI: File path: %s\n", nativeFileString);

共 (1) 个答案

  1. # 1 楼答案

    你正在做jchar filename = env->GetCharField(baseClass, fid);

    但是fidLjava/lang/String;类型的字段,而不是char。因此,您应该使用env->GetObjectField()获取String,然后按照该链接所述进行操作

    您还可以通过在每一行之后添加env->ExceptionDescribe()来更好地调试它,以查看在您对env的调用之后是否抛出了一个Exception(这只是为了调试,在实际的生产代码中,您应该在每次env调用之后检查异常,并在出现错误时执行某些操作)

    顺便说一句,也许您的代码只是一个示例,但是如果这是您真正的代码,那么将native方法声明为static并将字符串作为参数传递就容易多了