java - 通过 jni 将相同的 Android surfaceview 传递给 C++ 代码会导致不同的值

标签 java android c++

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

More

我不久前遇到过这个问题。传递给 JNI 函数的 jobject 可以有不同的值,即使它们指向相同的对象。发生这种情况是因为 JVM 有某种本地对象池,如果它们没有全局引用,它的每个 tick 都会将所有本地对象清除到 GC。 因此,如果您想在 C++ 代码中存储指向 jobject 的指针,则必须从本地引用创建全局引用。请不要忘记使用 env->DeleteGlobalRef 释放它 一旦您完成了您的对象,否则您的程序将发生内存泄漏。

关于java - 通过 jni 将相同的 Android surfaceview 传递给 C++ 代码会导致不同的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37940582/

相关文章:

java - Java 和 C/C++ 之间进程间通信的最快(低延迟)方法

java - 如何为 travis CI 指定 JDK 版本

java - 1. 扫描当前(相对于下一个)行位置。 2.扫描线X(Java初学者)

android - 条码扫描 是否有用于获取产品详细信息等的 API?

java - 将文件从文件阵列复制到目录

java - Android:使用搜索栏逐渐改变多个 ImageView 背景的颜色

c++ - 在不复制代码的情况下从工厂实例化对象(例如炮塔)的草图(即原型(prototype))

java - java集合对应的ruby数据结构实现

java - 我们如何告诉 log4j 属性文件在哪里?

c++ - 包含相邻顶点列表的自定义顶点类型 [图形] : incomplete type error