我的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(文件名)不正确,但我无法说出其他选择。
我试过这个: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无关。
谢谢。
更新: 我能够让一位朋友看一下它,并让它与之合作:
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);
答案 0 :(得分:3)
你正在做jchar filename = env->GetCharField(baseClass, fid);
但fid
是Ljava/lang/String;
类型的字段,而不是char
。因此,您应该使用String
获取env->GetObjectField()
,然后按照该链接说明的内容。
您还可以通过在每行之后添加env->ExceptionDescribe()
来更好地调试此问题,以查看在调用Exception
之后是否抛出了env
(这只是为了调试,实际上是生成代码,您应该在每次env
调用后检查异常,并在出现问题时执行某些操作。
顺便说一下,也许你的代码只是一个例子,但如果这是你真正的代码,那么将native
方法声明为static
并将字符串作为参数。