//Android
SurfaceView SW;
function doSomthing()
{
startPreview(SW);
snapShot(SW);
}
//C++
startPreview(jobject window)
{
TDebug("w1 = %u",window);
}
snapshot(jobject window)
{
TDebug("w2 = %u",window);
}
参数转换过程如下。
SurfaceView ->Object->Jobject(jni)->void*(C++)
为什么 w1 != w2
?
All JNI methods accept both local and global references as arguments. It's possible for references to the same object to have different values. For example, the return values from consecutive calls to NewGlobalRef on the same object may be different. To see if two references refer to the same object, you must use the IsSameObject function. Never compare references with == in native code.
One consequence of this is that you must not assume object references are constant or unique in native code. The 32-bit value representing an object may be different from one invocation of a method to the next, and it's possible ?that two different objects could have the same 32-bit value on consecutive calls. Do not use jobject values as keys.
最佳答案
因为 jobject window
是一个 local reference .如果你想比较两个对象引用是否指向同一个对象,你必须使用 JNIEnv*
和 IsSameObject
它的成员函数
static jobject window1=nullptr;
static jobject window2=nullptr;
Java_your_prefix_class_startPreview(JNIEnv *env,jobject thiz,jobject window){
window1=env->NewGlobalRef(window);
}
Java_your_prefix_class_snapshot(JNIEnv *env,jobject thiz,jobject window){
window2=env->NewGlobalRef(window);
TDebug("windows are equal = %d", env->IsSameObject(window1, window2));
}
我不久前遇到过这个问题。传递给 JNI 函数的 jobject
可以有不同的值,即使它们指向相同的对象。发生这种情况是因为 JVM 有某种本地对象池,如果它们没有全局引用,它的每个 tick 都会将所有本地对象清除到 GC。 因此,如果您想在 C++ 代码中存储指向 jobject 的指针,则必须从本地引用创建全局引用。请不要忘记使用 env->DeleteGlobalRef 释放它
一旦您完成了您的对象,否则您的程序将发生内存泄漏。
关于java - 通过 jni 将相同的 Android surfaceview 传递给 C++ 代码会导致不同的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37940582/