【问题标题】:Shared Library with JNI: how to maintain global variables?与 JNI 共享库:如何维护全局变量?
【发布时间】:2013-03-26 13:10:42
【问题描述】:

我编写了一个共享库,可以通过我的 linux 系统和来自 java 的 JNI 调用访问它。

该库应该有一个全局环形缓冲区,它必须在 JNI 方法和其他本地方法中可用。

我认为这不会是一个问题,因为当我从不同的程序访问 SL 时,全局变量总是应该的。

但是现在,在我的 JNI 方法中,全局变量似乎没有被初始化(它们应该是程序流强制的)。

这是我的例子:

ringbuf_t ringbuffer;

void internalMethod() {
    // this method is first called from system-program
    ringbuffer = ringbuf_new(5000);
}


JNIEXPORT jint JNICALL Java_example_read(JNIEnv *env, jobject This) {
    // this method is later called via JNI
    if (!ringbuffer) {
        LOGI("uhhh, why is that buffer not set?!");
    }
}

我必须做些什么才能使 ringbuffer 变量真正成为全局变量,以便每个实例/对共享库的调用都访问该变量的同一个实例?

【问题讨论】:

  • 您确定正在调用internalMethod() 吗?
  • 我将通过日志记录快速重新检查它。看来你也想知道。啊,我认为调用发生在不同的进程中,是这个问题吗?
  • > 你确定 internalMethod() 被调用了吗? ...是的,我现在绝对确定。 SL 的 __attribute__((constructor)) 方法也被调用了两次,一次来自 System.loadLibrary,一次通过系统内部程序。
  • 不同的进程有不同的内存,这是进程定义的一部分
  • 嗯,这是我的第一个 SL,由于我的监控,我认为(并且想知道!!)SL 的全局变量确实是全局的。所以我现在已经用这个想法对其进行了编程。这个问题有解决办法吗?

标签: android c java-native-interface shared-libraries shared-memory


【解决方案1】:

从 cmets 看来,您希望在一个进程中分配内存并在另一个进程中使用它。

为此,查看共享内存可能是个好主意:“man shmget”应该是一个好的开始。

请注意,这与 JNI 无关,是操作系统的限制。

编辑: 我建议你:

  1. 阅读共享内存 - 您应该了解其工作原理。
  2. 首先尝试在 2 个简单的应用程序之间共享内存
  3. 然后才在您的 JNI 应用程序中实现

【讨论】:

  • 是的,没错。如果尚未分配,我在进程#1 中分配一个环形缓冲区,并在进程#1 中写入它。然后我想在流程#2 (JNI) 中从中获取数据。理解和改变它会非常有趣:)
  • 正如您在示例中看到的,我使用的是 ringbuffer-struct。缓冲区本身是通过 ringbuf_new() 方法中的 malloc() 创建的。我是否还必须用 shm 方法替换这个 malloc,或者将 ringbuffer 存储到共享内存中就足够了?
  • 由于我在 Android 下,很遗憾我没有可用的 SHMEM(但 ASHMEM)。你把我推向了正确的方向,谢谢!
  • 您可以直接写入共享内存(就像写入文件一样)。如果您打算同时写入和读取此缓冲区,您还应该对生产者-消费者问题进行一些研究。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-12
  • 1970-01-01
  • 2014-05-17
  • 2011-11-10
  • 1970-01-01
  • 2017-08-19
  • 1970-01-01
相关资源
最近更新 更多