【问题标题】:How are the static variables in C++ code managed with JNI?如何使用 JNI 管理 C++ 代码中的静态变量?
【发布时间】:2014-09-09 14:10:26
【问题描述】:

我的问题是,假设我有一个带有单例的 c++ 类,并通过 JNI 方法调用这个单例,每次我从 java 调用到 c++ 时,单例变量是否会因为它的静态而改变,还是保持不变?并且每次我从 java 调用到 c++ 时它是否在新线程上运行该方法?

示例代码:

在 Java 中:

class NativeLib
{
  public native void updateFrame();
}

在 C/C++ 中:

JNIEXPORT void JNICALL Java_com_Company_NativeLib_NativeLib_updateFrame()
{
   sceneManager::getInstance()->updateFrame();
}

sceneManager::getInstance() 在每次调用时是否返回新实例或最新创建的实例,因为它是一个静态变量。

我在 android 中的主要问题是我的应用程序崩溃而没有显示任何类型的 logCat 信息为什么它崩溃了。

但如果我评论 sceneManager::getInstance()->updateFrame(); ,它永远不会崩溃,所以我认为当 Java 调用 C++ 时它位于一个新线程中,这意味着静态变量不会

【问题讨论】:

    标签: java android c++ android-ndk java-native-interface


    【解决方案1】:

    将 VM 视为您的应用程序调用的 C/C++ 代码库。有时它会回调您的代码。

    不会重新创建单例——它只是一个方法调用。 Dalvik VM 线程只是 pthreads,从 Java 语言代码执行本机调用的线程将是执行 C++ 代码的线程。

    最好的办法是附加一个本机调试器。 FWIW,在 logcat 中什么都没有崩溃的一种方法是让本机递归溢出堆栈。另一种方法是更改​​ SIGSEGV / SIGBUS 和朋友的信号处理程序。

    【讨论】:

    • 感谢 Fadden 的回答,实际上我根本没有更改信号处理程序,而且我没有找到任何使用递归的代码。当我实现 onDrawFrame(GL10 gl) 方法时,我认为 GLSurfaceView.Renderer 它在与主线程不同的线程上工作。不知何故,我注意到当我通过 jni 从 java 调用 c++ 时,调用发生在不同的线程中,对吗?我的问题是,当我们加载 .so 文件时,VM 是否会将其保存在内存中,直到应用程序结束或每次调用它再次加载或有时由 Dalvik VM 卸载,不是每个 .so 都有自己的堆栈吗?跨度>
    • GLSurfaceView 渲染器在自己的线程上运行。从该线程调用的本机代码也将在该线程上运行。仅加载 .so 文件的一个实例,并且它永远不会被 VM 卸载。没有与 .so 关联的堆栈——它只是代码和数据。顺便说一句,应用程序可以在没有警告的情况下停止的另一个原因是如果有人调用 exit(),所以请确保库没有这样做。
    • 谢谢你真的很有帮助!!
    • “不会重新创建单身人士” - 这是否总是成立?如果共享对象被卸载,单例将在卸载时被销毁。稍后,如果另一个 Java 类重新加载该库,那么它将再次重新创建。
    • 共享库被卸载的唯一方法是你的代码调用dlclose()——VM不能这样做,因为它不知道你的C++对象的生命周期。卸载库不会破坏您的对象;在 dlclose() 之后执行的 C++ 析构函数是导致本机崩溃的好方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-17
    • 2010-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多