gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 19:49:08 26 4
gpt4 key购买 nike

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

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

对于 jstring,当对象“超出范围”时,它调用 GetStringUTFChars 来获取资源并调用 ReleaseStringUTFChars 来释放。

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

最佳答案

您可以使用 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
}

如果您卡在 C++03 中并且无法访问 std::unique_ptrboost::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
}

† 您也可以在此处使用特定的 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));

关于c++ - 用于获取/释放资源的 JNI C++ 模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13017271/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com