Search code examples
javac++java-native-interfacecharsequence

How to convert java CharSequence to c++ char* through JNI


I feel that this should have a simple answer as I can do it easily with a java String, but something is going wrong with the CharSequence. My java code initializes a cppGenerator, passes a functionBlock object to its generateImplementation method, and returns a CharSequence. Here is my code:

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

This logic has worked for me when using String but this function returns a CharSequence. No classes, objects, or methods are returning null. The program crashes in jni.h attempting to call GetStringUTFChars. So i know I cannot use this method for CharSequence. Is there just a jni method I am missing or do I have to do something completely different for a CharSequence?


Solution

  • You can't just cast mid to jstring and call GetStringUTFChars (since mid might not be a String, which seems to be the case). There is no convenience method like GetStringUTFChars for CharSequences like there is for Strings.

    You'd have to do it the inconvenient way of calling 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()'...