2017-07-07 1 views
0

Je pense que cela devrait avoir une réponse simple car je peux le faire facilement avec un String java, mais quelque chose ne va pas avec le CharSequence. Mon code Java initialise un cppGenerator, transmet un functionBlock object à son generateImplementation method et renvoie un CharSequence. Voici mon code:Comment convertir java CharSequence en C++ char * en JNI

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

Cette logique a travaillé pour moi lors de l'utilisation String mais cette fonction retourne un CharSequence. Aucune classe, aucun objet ou méthode ne renvoie null. Le programme se bloque en jni.h en essayant d'appeler GetStringUTFChars. Donc je sais que je ne peux pas utiliser cette méthode pour CharSequence. Y at-il juste une méthode jni qui me manque ou dois-je faire quelque chose de complètement différent pour un CharSequence?

Répondre

1

Vous ne pouvez pas simplement jeter mid-jstring et appeler GetStringUTFChars (depuis mid pourrait ne pas être un String, ce qui semble être le cas). Il n'y a pas de méthode pratique comme GetStringUTFChars pour CharSequence s comme il y a String s.

Il faudrait faire la façon pratique d'appeler 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. C'est ce que je cherchais. Je pensais que je devrais faire quelque chose comme ça s'il n'y avait pas de méthode intégrée. Merci cela fonctionne parfaitement pour mon code. –

+1

Etes-vous sûr de ne pas recevoir d'avertissement ici: jchar est plus large que char? Dans tous les cas, le rétrécissement est à la fois sans perte et précis si le jeu de caractères cible est ASCII ou ISO 8859-1. Vous pouvez utiliser 'std :: wstring' pour rester avec UTF-16 (jchar). –

+0

@TomBlodget J'avais oublié ce fait. Mais avoir un encodage compatible est une condition préalable pour utiliser 'GetStringUTFChars' de toutes les façons, donc cela devrait toujours être un équivalent correct. –

0

Pourquoi ne pas utiliser toString directement?

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