【问题标题】:Can I use C++ exceptions in JNI library on Android?我可以在 Android 上的 JNI 库中使用 C++ 异常吗?
【发布时间】:2012-11-16 14:10:41
【问题描述】:

有什么方法可以在 Android 上的 JNI(Java 本地接口)库中使用 C++ 异常?

编辑:我说的是完全在 JNI 库内部的 C++ 异常处理。也就是说,异常在库中被抛出和捕获,并且永远不会逃出库。

根据 Android 文档 (docs/CPLUSPLUS-SUPPORT.html),仅当我使用 'GNU libstdc++' 作为 C++ 运行时而不是默认值时,才支持异常。

问题在于文档还声明程序的所有部分都必须使用相同的 C++ 运行时:

"您只能选择一个 C++ 运行时 您的代码将取决于。无法混合编译的共享库 针对不同的 C++ 运行时。”

根据我的解释,这意味着我不得不使用与 Dalvik(Android 上的 Java VM)相同的 C++ 运行时。

那么,如果 Dalvik 不使用“GNU libstdc++”,我还有办法在我的 JNI 库中使用异常吗?

Dalvik 是针对什么 C++ 运行时编译的?

编辑:我必须假设无论哪个 Java 应用程序正在使用我的 JNI 库,可能还想使用其他 JNI 库,我无法控制。这会以任何方式限制我的选择吗?

【问题讨论】:

  • 您还没有定义“使用例外”的含义。您是否只想在同一个库中使用异常(即在同一个库中尝试/捕获),然后使用 GNU libstdc++ 运行时它会起作用。另一方面,如果你希望从你的 JNI 库中抛出一个异常并在你的 Java 代码中捕获它,那么这是行不通的。
  • @CadentOrange 我现在有了 - 谢谢。
  • 一般来说,是的,您可以在 JNI 中使用 C++ 异常。但是,您必须确保 C++ 异常不会跨越语言障碍(即从您的 JNI 公开函数中逃脱)。如果 C++ 异常逃逸到 JNI 中,您的应用很可能会终止或中止。
  • @CadentOrange:请注意,JNI 定义了从本机代码抛出 Java 异常的函数。不过,这些并不等同于 C++ 异常。

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


【解决方案1】:

是的,您可以使用例外

APP_STL := gnustl_static

gnustl_shared。该文档使用了一种令人生畏的语言,但他们只希望您不要在在您的应用程序中混合使用不同 STL 实现的库。这就是为什么设置有APP_ 前缀,而不是LOCAL_

Dalvik VM 完全支持文档中列出的任何 STL 实现。

通常您控制 JNI 的两端,并且可以确保为 gnustl_shared 编译所有本机组件。这是首选方案。

如果您的业务是提供一个可供其他人使用的黑盒库,而这些人可能决定也包含其他库,那么选择gnustl_static 来支持您的代码中的 C++ 异常会更安全。这样你就不会依赖别人的好意。您应该小心设计您的 API,以便您的原生对象(尤其是异常)永远不会暴露给其他组件。

【讨论】:

  • 好吧,这听起来令人鼓舞。但是假设一个 Java 应用程序同时使用了我的 JNI 库和其他一些 JNI 库。进一步假设其他 JNI 库使用,比如 APP_STL := stlport_static。这样的 C++ 运行时混合仍然有效吗?这仍然不违反“禁止混合”规则吗?
  • 假设另一个 JNI 库也使用 APP_STL := gnustl_static。然后似乎我违反了同一文档文件中的以下规则:“另一方面,如果您的项目中有两个共享库(例如 libfoo.so 和 libbar.so),它们都链接到同一个静态运行时,它们中的每一个都将在其最终二进制映像中包含运行时代码的副本。这是有问题的,因为运行时内部使用/提供的某些全局变量是重复的。文档接着提到了几个关键问题。
  • 这两个问题基本上都是正确的。当您的应用程序中有多个本机库时,我建议使用相同的 _shared STL 实现。但实际上,如果这两个 JNI 库从不相互交互,那么您提到的全局变量的重复和其他麻烦是无关紧要的。
  • 您说如果两个 JNI 库从不交互,它可能会起作用。如果一个 Java 应用程序调用一个 JNI lib,然后调用另一个,那是交互吗?不过,还有哪些问题需要我注意?
  • 'Interact' 可能是一个 JNI 库创建了一个 std::string 或 std::list,并将其句柄传递给 Java,Java 将这个句柄提供给另一个 JNI 库。全局变量的重复可能会影响应用的性能和内存消耗。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-17
  • 2014-07-29
  • 1970-01-01
  • 2010-10-07
  • 1970-01-01
相关资源
最近更新 更多