在2个本机模块之间传递数据(Android NDK)

时间:2011-10-24 09:10:31

标签: android c shared-libraries native android-ndk

这是我的程序的结构: - 2个独立的模块libA和libB,每个模块都是一个共享库libA.so和libB.so - 创建2个线程thA和thB的java活动,每个线程从一个库调用本机JNI函数(从libA.so调用函数和从libB.so调用函数)。

我想在两个库之间传递本机类型的数据(Java不知道任何内容,包含Java无法处理的指针等类型),但我找不到任何方法让它们进行通信。

假设两个库都知道本机类型“typeA”的定义,有没有办法将typeA的对象从libA传递到libB(最好不必复制VM内存中的数据)。传递一个内存指针可能??

由于

2 个答案:

答案 0 :(得分:1)

我在我正在处理的应用程序中正是这样做的。我在libA中分配内存,并通过JNI将指针作为long返回到Java。然后,我在libB中调用一个函数,将指针向下传递,以便可以访问它。

然而,这种天真的方法存在问题。虽然它有时可能有效,但如果libA和libB存在于不同的RAM页面上,触摸libB中的指针可能会使程序崩溃。报告崩溃的原因可能因构建和运行而异,因此调试很困难。更糟糕的是,如果分配的内存部分驻留在一页RAM上,而部分驻留在另一页上,只有当你遇到边界时,你才会崩溃,因此可能无法立即检测到问题。我设法多次杀死操作系统并产生任何数量的各种错误。如果您的库很小并且装在相邻的内存中,那么几率很高就可以了。 Android上的原生应用程序可以摆脱vanilla Java应用程序无法解决的问题。

解决方案:

  1. Ashmem将允许您在应用程序之间创建共享内存空间。如果您不熟悉Android开发或Linux操作系统,可能会出现学习曲线。

  2. 您可以在两个应用程序之间使用Socket并传输数据。

  3. 您可以将数据从libA通过JNI functions直接发送到Java创建的缓冲区,该缓冲区的大小必须适合来自libA的数据。然后,您可以再次通过JNI将其传递给libB。此解决方案速度较慢,成本可能会使您开始使用本机代码的原因无效,但如果您的问题与内存相关或程序逻辑固有,则调试和发现它是一种很好的方法。

答案 1 :(得分:0)

将指针从A传递到B可能是一种选择。这取决于库中typeA的实时循环。确保在一个库中未删除typeA对象,而另一个库中仍然使用它。

传递指针的一种方法是遍历JNI并使用jlong​​ / long来表示指针。

相关问题