【问题标题】:Android NDK: Static or shared C++ runtime for 3rd-party Java libraryAndroid NDK:第三方 Java 库的静态或共享 C++ 运行时
【发布时间】:2018-09-18 13:37:38
【问题描述】:

我正在为使用 JNI 的 Android 编译第 3 方 Java 库。我阅读了有关在 developer.android 上添加 C++ 支持的相关页面,但我仍然对有关 C++ STL 运行时的几个问题感到困惑,我希望我能在这里澄清:

1- 我的库无法控制将嵌入的应用程序,因此我不知道是否会有其他库可能使用静态/共享 STL。如果我使用带有 ANDROID_STL=c++_static 的静态 C++ 运行时,它是否安全,或者我是否应该担心另一个库可能正在使用可能与我的冲突的 gnustl_static 之类的东西?

2- 如果我使用 ANDROID_STL=c++_shared 的共享 C++ 运行时,是否可以保证 STL 中的特定元素将使用 libc++ 运行时,或者如果它不存在,是否可以使用 gnustl ?例如,如果我在具有另一个 gnustl_static 库的应用程序中使用带有共享 c++ 运行时 (c++_shared) 的 std::string,我的 std::string 实现会取自 libc++ 还是 gnustl?

理想情况下,我希望有一个非常精简的静态 c++ 运行时版本,其中 (c++_static) 仅包含 std::vector、std::string 和 std::map。我实际上打算使用这里和 #768 中描述的 -ffunction-sections 之类的东西。

请多多指教,谢谢。

环境详情

  • Pkg.Desc = Android NDK
  • Pkg.Revision = r15c
  • Android Studio = 3.1.2
  • 系统:cmake 主机操作系统:Arch Linux ($ uname -r % 4.18.5-arch1-1-ARCH)
  • 编译器:Clang++
  • STL:c++_static/c++_shared

【问题讨论】:

  • 另外请记住,GnuSTL 已被弃用,将从 r18 开始从 NDK 中删除。如果你想暂时同时支持 libc++ 和 gnustl,解决方案可能是提供你的库的两个变体。
  • 嘿@Michael,我读了那个页面。我了解有关“静态”链接的部分,但它没有提及有关 shared 运行时状态的任何内容。我发现与该问题相关的唯一一个是这个旧文档:android.googlesource.com/platform/ndk/+/ics-mr0/docs/…
  • 该页面的 "One STL Per App" 部分未提及静态链接,因此我认为该部分是普遍适用的,无论是静态链接还是动态链接使用 STL。
  • 那么第三方库如何确保它不会创建额外的 STL(静态),也不会使用不符合应用环境的 STL?我相信 Facebook 的 Yoga 只是有一个 c++_static 运行时,并假设每个人都会使用 c++ 运行时

标签: android c++ cmake stl android-ndk


【解决方案1】:

您的担忧是非常真实的。但如果处理得当,你可以找到一个稳健的出路。

关于在应用程序中的所有库中使用单个 C++ 运行时的警告(以及将 NDK 中的 C++ 支持定义为 APP_STL 与大多数其他标志(例如 LOCAL_CFLAGS 或 LOCAL_SHARED_LIBRARIES)的整个想法,与连接的本机库相关。从不直接通信的 JNI 库(通过其相应的 Java 层除外)可以使用不同的 C++ 运行时。另一点是正常构建只会将一个 C++ 运行时共享库​​打包到 APK 中。请注意,版本控制也是一个潜在的危险:如果开发人员添加您的库的人使用不同的 NDK 版本,当他的 STL 运行时版本与您的代码一起使用时,可能会出现冲突或意外的副作用。

因此,为了获得最大的灵活性,您的库应该使用静态 C++ 运行时。这可能会影响二进制文件的大小,但如您所说,如果您只使用 STL 的有限子集,那么这个额外的部分将会相当小。

最重要的是,如果使用libc++_static 构建共享库,您将不必担心。

【讨论】:

  • 感谢科恩先生的回答。我同意你关于沟通的看法,幸运的是我不会发生这种情况。为了将来清楚起见,我将链接我从 NDK 的一位维护者那里收到的额外答案:github.com/android-ndk/ndk/issues/796#issuecomment-422560209 简而言之,他的意见是在 r16 之后使用c++_shared,因为不推荐使用 gnu_stl(静态和共享)。如果用户拥有多个 STL,则“可能”会出现关于名称错误的问题。因此,如果该库不与其他库通信,则使用c++_static 应该更安全,如您所述。
  • 这个问题让我很困惑,所以我一定会尝试做一个小文章并在这里链接它,我一定会提到你的名字。再次感谢科恩先生。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多