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, NU开发者_Go百科LL);
// 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.
精彩评论