简体   繁体   中英

Extending my Java API to C++ through JNI: How to wrap a method returning a String?

I am using JNI to extend my API in Java, in order to make it accessible through C++ (I am creating wrapper classes). I am experienced in Java but new to C++.

Now, I am creating a wrapper in C++ for a Java function getString() which returns a String. I am using GetStringUTFChars to get the C string from the Java String but I don't know where to use ReleaseStringUTFChars which releases the C string. Here is my code (aClass and aClassInstance are private date members inside the wrapper class):

const char* getString() {
jmethodID methodID = env->GetMethodID(aClass,
        "methodName",
        "()Ljava/lang/String;");
if (methodID == NULL) {
    cout << "--methodID = NULL";
    exit(0);
}
jstring jstringResult = (jstring) env->CallObjectMethod(aClassInstance, methodID);
const char* result = env->GetStringUTFChars(jstringResult, NULL);
// env->ReleaseStringUTFChars(jstringResult, result); 
return result;
}

If I remove the // and use ReleaseStringUTFChars, result will be released and I will no longer be able to return it, right? Should I copy result to another char array before releasing it?

Thanks, any help is welcome!

K

Mahesh is right

std::string getString()
{
    jmethodID methodID = env->GetMethodID(aClass,
        "methodName",
        "()Ljava/lang/String;");
    if (methodID == NULL)
    {
        cout << "--methodID = NULL";
        exit(0);
    }
    jstring jstringResult = (jstring) env->CallObjectMethod(aClassInstance, methodID);
    const char* result = env->GetStringUTFChars(jstringResult, NULL);
    std::string result2(result);
    env->ReleaseStringUTFChars(jstringResult, result); 
    return result2;
}

std::string takes copies your characters for you and will automatically free when needed. Using raw pointers in C++ is generally frowned upon. Coming from Java you probably have little idea of the problems they can cause.

The most obvious place to call ReleaseStringUTFChars is in your wrapper class' destructor. Use a vector or some other container to record each jstring as it's accessed, and then in your wrapper class' destructor, call ReleaseStringUTFChars on every element in the container. Your clients will need to make copies of the character data if they live longer than the wrapper class object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM