2017-07-07 57 views
0

我覺得這應該有一個簡單的答案,因爲我可以用java String輕鬆完成,但CharSequence出了問題。我的java代碼初始化一個cppGenerator,將一個functionBlock object傳遞給它的generateImplementation method,並返回一個CharSequence。這裏是我的代碼:如何通過JNI將java CharSequence轉換爲C++ char *

jobject fBlock = env->CallObjectMethod(structuredTextModel, getFunction); 
jclass CPPGenerator = lookForClass(env, "Path/CPPGenerator"); 
jobject CPPGeneratorImpl = invokeClassObj(env, CPPGenerator); 
    jmethodID generateImplementation = env->GetMethodID(CPPGenerator, "generateImplementation", "(LPath/FunctionBlock;)Ljava/lang/CharSequence;"); 
jobject mid = env->CallObjectMethod(CPPGeneratorImpl, generateImplementation, fBlock); 
jstring jresult = (jstring)mid; 
char* result = (char*)env->GetStringUTFChars(jresult, 0); 

使用String時,這種邏輯很適合我的工作,但這個函數返回一個CharSequence。沒有類,對象或方法返回null。該程序崩潰在jni.h試圖撥打GetStringUTFChars。所以我知道我不能使用CharSequence的這個方法。是否只有我缺少的jni方法,或者我必須爲CharSequence做一些完全不同的事情?

回答

1

你不能只投midjstring並調用GetStringUTFChars(因爲mid可能不是一個String,這似乎是如此)。對於CharSequence,沒有像GetStringUTFChars這樣的簡便方法,就像String s一樣。

你不得不去做調用charAt的不便方式:

jclass cCharSequence = env->FindClass("java/lang/CharSequence"); 
jmethodID mLength = env->GetMethodID(cCharSequence, "length", "()I"); 
jmethodID mCharAt = env->GetMethodID(cCharSequence, "charAt", "(I)C"); 

int length = env->CallIntMethod(mid, mLength); 
std::string str; 
str.reserve(length); 
for(int i = 0; i < length; i++) { 
    str += env->CallCharMethod(mid, mCharAt, i); 
} 

// use 'str.c_str()'... 
+0

ahah,charAt。這就是我一直在尋找的。我想如果沒有內置的方法,我將不得不這樣做。謝謝你對我的代碼完美的作品。 –

+1

你確定在這裏沒有得到警告:jchar比char更寬嗎?在任何情況下,只有當目標字符集是ASCII或ISO 8859-1時,縮小纔是無損和準確的。你可以使用'std :: wstring'來保留UTF-16(jchar)。 –

+0

@TomBlodget我忘記了這個事實。但是,兼容編碼是以任何方式使用'GetStringUTFChars'的先決條件,所以這應該仍然是一個正確的等價形式。 –

0

爲什麼不直接使用toString

jclass clzCharSequence = env->GetObjectClass(mid); 
jmethodID toString = env->GetMethodID(clzCharSequence, "toString", "()Ljava/lang/String;"); 
jobject s = env->CallObjectMethod(mid, toString); 
const char* cstr = env->GetStringUTFChars(static_cast<jstring>(s), NULL); 
// do something with cstr 
env->ReleaseStringUTFChars(static_cast<jstring>(s), cstr);