将std::unique_ptr传递给JNI
Passing std::unique_ptr to JNI
我正在用JNI包装一些C++代码,偶然发现了以下工厂函数:
std::unique_ptr<MetricPlanner> create_metric_planner(*arguments*)
我需要将对该函数创建的计划器的引用传递回Java以供以后使用,但我很困惑a) 如何将其传回来,以及b) 一旦它被传递出去会发生什么。
通常情况下,我是这样通过的:
Director *DIRECTOR = new Director(arguments);
return (jlong)DIRECTOR;
它就像一个符咒。
当使用返回这种类型指针的工厂函数而不是普通构造函数时,有人能解释用JNI引用对象的类似过程吗?
由于您将create_metric_planner
函数的返回值传递给Java,然后再使用它,因此不希望unique_ptr
在其作用域结束时破坏返回值。要执行此操作,必须调用unique_ptr::release
。
return (jlong)create_metric_planner( ... ).release();
不要忘记,在某个时刻,当您使用完该函数返回的对象时,您必须delete
它(或者调用您正在使用的库提供的某个deleter函数)。
我使用以下代码创建、使用和删除带有std::unique_ptr
的对象,同时保持Java端的引用(即使在切换活动时也保持对象的活动性)。
创建对象并将指针传递给Java:
void Java_com_domain_project_activity_createObject(JNIEnv *env, jobject obj) {
Object* object = (std::makeUnique<Object>()).release();
env->SetLongField(obj, getPtrFieldId(env, obj), (jlong)object);
}
删除对象:
void Java_com_domain_project_activity_deleteObject(JNIEnv *env, jobject obj) {
Object* object = (Object*) env->GetLongField(obj, getPtrFieldId(env, obj));
delete object;
}
处理对象:
void Java_com_domain_project_activity_workOnObject(JNIEnv *env, jobject obj) {
Object* object = (Object*) env->GetLongField(obj, getPtrFieldId(env, obj));
// Work on object
}
最后,将指针存储在Java端:
jfieldID getPtrFieldId(JNIEnv * env, jobject obj)
{
static jfieldID ptrFieldId = 0;
if (!ptrFieldId)
{
jclass c = env->GetObjectClass(obj);
ptrFieldId = env->GetFieldID(c, "objPtr", "J");
env->DeleteLocalRef(c);
}
return ptrFieldId;
}
理想情况下,我不会在这些情况下使用unique_ptr
,只使用普通指针,但unique_ptr
在我的项目中是必需的。
我还发现这个网站非常有用:https://www.studiofuga.com/2017/03/10/a-c-smart-pointer-wrapper-for-use-with-jni/
相关文章:
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- std::向量与传递值的动态数组
- 使用std::vector的OpenCL矩阵乘法
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- std::condition_variable::wait()如何评估给定的谓词
- 如何获取std::result_of函数的返回类型
- std::原子加载和存储都需要吗
- 将对象移动到std::shared_ptr
- 如何从 JNI 传递 std::list 参数来调用本机 C++ 函数
- 将 JNI -> jobject(基本上是 java 文件中的映射和/或映射的映射)转换为 std::map(c++)
- std::华为JNI上的SIGSEGV异常
- std ::线程在Android JNI中引起sigabrt
- std::strtoull在我的JNI NDK环境下无法识别
- 将std::unique_ptr传递给JNI