Java 将std::unique_ptr传递给JNI 我用JNI包装了一些C++代码,偶然发现了以下工厂函数: std::unique_ptr<MetricPlanner> create_metric_planner(*arguments*)
这就像一个符咒Java 将std::unique_ptr传递给JNI 我用JNI包装了一些C++代码,偶然发现了以下工厂函数: std::unique_ptr<MetricPlanner> create_metric_planner(*arguments*),java,c++,c++11,java-native-interface,unique-ptr,Java,C++,C++11,Java Native Interface,Unique Ptr,这就像一个符咒 有人能解释一下当使用返回这种类型指针的工厂函数而不是普通构造函数时,使用JNI引用对象的类似过程吗?因为您将create\u metric\u planner函数的返回值传递给Java,然后在以后使用它,您不希望unique\u ptr在其作用域结束时销毁返回值。要做到这一点,你必须打电话 不要忘记,在某些时候,当您使用该函数返回的对象时,您必须删除它(或调用您正在使用的库提供的某个deleter函数)。我使用以下代码创建、使用和删除带有std::unique\u ptr的对象,
有人能解释一下当使用返回这种类型指针的工厂函数而不是普通构造函数时,使用JNI引用对象的类似过程吗?因为您将
create\u metric\u planner
函数的返回值传递给Java,然后在以后使用它,您不希望unique\u ptr
在其作用域结束时销毁返回值。要做到这一点,你必须打电话
不要忘记,在某些时候,当您使用该函数返回的对象时,您必须
删除它(或调用您正在使用的库提供的某个deleter函数)。我使用以下代码创建、使用和删除带有std::unique\u 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_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\u ptr
,只使用普通指针,但我的项目中需要unique\u ptr
我还发现这个网站非常有用:
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
}
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;
}