2015-07-14 3 views
0

у меня в классе Java строковую переменную:JNI jstring из переменной класса?

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 

Что я делаю неправильно, что ISN 't правильно преобразовать строку 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 

Кроме того, это просто JNI и Java 8 на OSX, ничего не связано с Android.

спасибо.

Update: Я был в состоянии получить друга, чтобы взглянуть на него, и получил его работать:

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

Просто передайте его как параметр для метода JNI. Постарайтесь не писать еще одну строку JNI, чем строго необходимо. – EJP

ответ

3

Вы делаете jchar filename = env->GetCharField(baseClass, fid);

Но fid является полем типа Ljava/lang/String;, не a char. Таким образом, вы должны получить String, используя env->GetObjectField(), а затем следуйте указаниям этой ссылки.

Вы также можете отлаживать это лучше, добавив env->ExceptionDescribe() после каждой строки, чтобы увидеть, если Exception выбрасывают после звонков в env (это было бы просто для отладки, в режиме реального производства кода вы должны проверять исключения после каждого env звоните и делайте что-нибудь, если что-то пойдет не так).

Кстати, может быть, ваш код является лишь примером, но если это ваш настоящий код, было бы намного проще объявить метод native как static и просто передать строку в качестве параметра.

+0

Мне удалось заставить его работать, GetObjectField() была подходящей функцией. –

Смежные вопросы