java - 来自类变量的 JNI jstring?

标签 java c++ java-native-interface

我的 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 和 Java 8,与 Android 无关。

谢谢。

更新: 我能够让一个 friend 看它,并让它与:

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);

最佳答案

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

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

您还可以通过在每一行之后添加 env->ExceptionDescribe() 来更好地调试它,以查看在调用 env 之后是否抛出了 Exception (这只是为了调试,在实际生产代码中,您应该在每次 env 调用后检查异常,并在出现问题时采取措施)。

顺便说一句,也许您的代码只是一个示例,但如果那是您的真实代码,那么将 native 方法声明为 static 和只需将字符串作为参数传递即可。

关于java - 来自类变量的 JNI jstring?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31418478/

相关文章:

java - JSF中是否有 "abstract"组件?

c++ - 寻找匹配元素的算法

c - 如何将 .pem 文件中的公钥传递给 Polarssl rsa_context

java - 从动态库调用 jni 时 JVM 堆内存不足

android - Android Studio 项目中 JNI/native 库的放置位置

java - 我可以使用 BufferedReader 并在 actionListener 类中创建一个数组吗?

java - 在 Eclipse 中将对象贡献转换为菜单贡献

java - ArrayList 的后备数组的长度与 ArrayList 的 .size() 不同

c++ - 无符号字符数组以键入 STL::map 或其他容器

c++ - 复制构造函数和重载的加法运算符