用于获取/释放资源的JNI C++模板

Sam*_*... 3 c++ java-native-interface templates release

从C++代码获取/释放JNI资源的推荐模板集或库是什么?

"坏"的例子:

//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);
}
Run Code Online (Sandbox Code Playgroud)

显然,每个人都使用模板集,而不是上面的代码.

对于jstring,当对象超出范围时,它调用GetStringUTFChars获取资源,释放ReleaseStringUTFChars.

必须与auto_ptr模板类似,但为JNI量身定制,例如为jstring调用GetStringUTFChars/ReleaseStringUTFChars.

Xeo*_*Xeo 8

您可以std::unique_ptr在C++ 11中使用,它允许您自己设置删除器:

#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
}
Run Code Online (Sandbox Code Playgroud)

如果你被困在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
}
Run Code Online (Sandbox Code Playgroud)

†您也可以在此处使用特定的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));
Run Code Online (Sandbox Code Playgroud)