[英]JNI C++ templates to acquire/release resources
What is recommended template set or library to acquire/release JNI resources from C++ code? 从C ++代码获取/释放JNI资源的推荐模板集或库是什么?
"Bad" example: “坏”的例子:
//C++ code
extern "C"
JNIEXPORT void JNICALL Java_ClassName_MethodName
(JNIEnv *env, jobject obj, jstring javaString)
{
//Get the native string from javaString
const char *nativeString = env->GetStringUTFChars(javaString, 0);
//Do something with the nativeString
//DON'T FORGET THIS LINE!!!
env->ReleaseStringUTFChars(javaString, nativeString);
}
Obviously, everybody uses a template set, not the code above. 显然,每个人都使用模板集,而不是上面的代码。
For jstring it calls GetStringUTFChars to acquire resource and ReleaseStringUTFChars to release, when object goes "out of scope". 对于jstring,当对象超出范围时,它调用GetStringUTFChars获取资源,释放ReleaseStringUTFChars。
Gotta be something similar to auto_ptr template, but tailored to JNI to call GetStringUTFChars/ReleaseStringUTFChars for jstring, for example. 必须与auto_ptr模板类似,但为JNI量身定制,例如为jstring调用GetStringUTFChars / ReleaseStringUTFChars。
You can use std::unique_ptr
in C++11, which allows you to set the deleter yourself: 您可以在C ++ 11中使用
std::unique_ptr
,它允许您自己设置删除器:
#include <memory>
#include <functional>
typedef std::unique_ptr<char const[], std::function<void(char const*)>> jni_string_ptr;
// the "std::function" is needed to store any callable†
extern "C"
JNIEXPORT void JNICALL Java_ClassName_MethodName
(JNIEnv *env, jobject obj, jstring javaString)
{
//Get the native string from javaString
jni_string_ptr nativeString(env->GetStringUTFChars(javaString, 0),
[=](char const* p) mutable{ env->ReleaseStringUTFChars(javaString, p); });
// lambda as the deleter
// mutable needed if "ReleaseStringUTFChars" is a non-const method
//Do something with the nativeString
// nativeString automatically calls the passed deleter
}
If you're stuck in C++03 and don't have access to std::unique_ptr
, boost::shared_array
provides a.. viable alternative. 如果你被困在C ++ 03中并且无法访问
std::unique_ptr
,那么boost::shared_array
提供了一个可行的选择。
#include <boost/shared_ptr.hpp>
typedef boost::shared_array<char const*> jni_string_ptr;
struct jni_string_deleter{
jni_string_deleter(JNIEnv* e, jstring js)
: _env(e), _java_string(js) {}
void operator()(char const* p) const{
_env->ReleaseStringUTFChars(_java_string, p);
}
private:
JNIEnv* _env;
jstring _java_string;
};
extern "C"
JNIEXPORT void JNICALL Java_ClassName_MethodName
(JNIEnv *env, jobject obj, jstring javaString)
{
//Get the native string from javaString
jni_string_ptr nativeString(env->GetStringUTFChars(javaString, 0),
jni_string_deleter(env, javaString));
//Do something with the nativeString
// nativeString automatically calls the passed deleter
}
† You can also use a specific delter type here, as with the shared_array
example, to avoid the type-erasure overhead of std::function
: †您也可以在此处使用特定的delter类型,与
shared_array
示例一样,以避免std::function
的类型擦除开销:
struct jni_string_deleter{
jni_string_deleter(JNIEnv* e, jstring js)
: _env(e), _java_string(js) {}
void operator()(char const* p) const{
_env->ReleaseStringUTFChars(_java_string, p);
}
private:
JNIEnv* _env;
jstring _java_string;
};
typedef std::unique_ptr<char const[], jni_string_deleter> jni_string_ptr;
// create
jni_string_ptr(env->get_the_chars(), jni_string_deleter(env, javaString));
The keyword here is RAII : 这里的关键字是RAII :
class jni_string {
public:
jni_string(JNIEnv *env, jstring javaString)
: env_(env), javaString_(javaString)
{ nativeString_ = env_->GetStringUTFChars(javaString_, 0); }
~jni_string() { env_->ReleaseStringUTFChars(javaString_, nativeString_); }
operator const char *() const { return nativeString_; }
private:
jni_string(const jni_string &x);
jni_string &operator=(const jni_string &x);
JNIEnv *env_;
jstring javaString_;
const char *nativeString_;
};
Usage would be: 用法是:
//C++ code
extern "C"
JNIEXPORT void JNICALL Java_ClassName_MethodName
(JNIEnv *env, jobject obj, jstring javaString)
{
//Get the native string from javaString
jni_string nativeString(env, javaString);
//Do something with the nativeString
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.