JNI:MAP jobject到本机C 对象

JNI: map jobject to native c++ object

本文关键字:本机 对象 jobject MAP JNI      更新时间:2023-10-16

我使用常规std ::映射将jobject的映射到c 对象。这种方法的问题在于,其他类型的参考可能会失败,例如全局引用实际上是指指针与常规本地参考不同,即使它们引用了同一对象。比较两个引用是否参考相同对象的正确方法是:

env->IsSameObject(jobj1, jobj2);

那么,我的问题是:将局限性映射到C 对象的正确方法是什么?对包裹求解的明显答复到某些C 类中,该类使运算符==和CALL ISSAMEOBJECT并不是我要寻找的答复。我想知道是否有办法在JVM和本机C/C 之间进行每个比较操作,而无需来回操作。

编辑:全局参考是JNI全局参考,与C 参考无关。

edit2:我想澄清此代码的问题:

std::map<jobject, void *> jobjs;
jobject obj1, obj2;
... some code that sets these obj1 and obj2 to some Java objects.
jobjs[obj1] = new CppPeer;
CppPeer * = jobjs[obj1]; //OK...
if(objs.find(obj2) == objs.end()){
   assert(obj2 != obj1);
   //Here's the problem: here a new c++ CppPeer
   //created for obj2, but the problem is that 
   //even if obj1 != ob2 it doesn't mean that
   //they actually reference different java objects
   //On the next line error might happen
   jobjs[obj2] = new CppPeer; //maybe not OK here...
}

IssameObject的另一个问题是它使事情变得非常讨厌和混乱。不仅现在,我还需要保留一个指针到JVM,而且只要我需要比较我需要附加线程等的锻炼,才能将指针转到Jnienv,以便能够检查Jobight

edit3:请注意,根据Android文档,您甚至不能假设两个参考文献在同一对象相等的情况下引用相同的对象。我不知道这是怎么可能的,但是有来自Android的JNI提示页面的部分:

这样的结果是,您不得假设对象引用 在本机代码中是恒定或唯一的。代表32位值 一个对象可能与一个方法调用到 接下来,两个不同的对象可能具有相同的 连续呼叫的32位值。请勿将jobight值用作密钥

免责声明:闻起来。

在Android上,指针和jint的大小相同。考虑在您的Java类中添加一个int字段,以存储用于本机ConterPart的指针。当使用JNI方法时,将其返回指针。

要在稍微更安全的一面,请在数据类型上进行静态断言:

{char a[sizeof(void*) == sizeof(jint) ? 1 : -1]};

如果它是在没有的系统上编译的,您将遇到汇编错误。

如果气味稍小一点,请使用静态/全局map从int到您的对象,使用ID生成器,而不是对象指针存储相对唯一(在过程寿命内)java对象中的对象ID。

<</p> <</p>