2011-10-24 55 views
3

这里是我的程序结构: - 2个独立模块libA和libB,每个模块都是一个共享库libA.so和libB.so - 创建一个java活动2个线程thA和thB,它们中的每一个都从一个库(从libA.so调用函数和从libB.so调用函数)调用本地JNI函数。在2个本地模块(Android NDK)之间传递数据

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

如果两个库都知道原生类型“typeA”的定义,是否有办法将类型A的对象从libA传递到libB(最好不需要将数据复制到VM内存中)。传递一个内存指针可能?

谢谢

回答

0

将指针从A传递给B可能是一个选项。它依赖于库中类型A的生命周期。确保一个库中的typeA对象在另一个库中仍在使用中时不会被删除。

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

+0

请您详细说明如何在thA/thB线程间切换,例如如何在线程thA处于活动状态时在线程thB上运行一些代码?另请参阅我的问题http://stackoverflow.com/questions/8667117/updating-ui-from-background-thread-using-ndk-entirely-no-jni。 – youri

1

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

但是,这种天真的方法有问题。虽然它有时可能有效,但如果libA和libB存在于RAM的不同页面上,则触摸libB中的指针可能会导致程序崩溃。报告崩溃的原因在构建和运行时可能会有所不同,这使得调试变得困难。更糟糕的是,如果分配的内存部分驻留在RAM的一页上,而部分驻留在另一页上,则只有当您触及边界时,才会崩溃,因此可能无法立即检测到问题。我已经成功地杀死了操作系统,并产生了许多种各样的错误。如果你的图书馆很小,并装载在邻近的记忆,赔率是好的,你会没事的。 Android上的本机应用程序可以避免Java应用程序无法做到的事情。

解决方案:

  1. Ashmem将允许您创建的应用程序之间共享内存空间。如果您是Android开发人员或Linux操作系统的新手,这可能会以学习曲线出现。

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

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