Android Studio NDK 入门教程(7)--被NDK支持的C++运行库
概述 Android 默认使用的是最小系统c++运行库,功能十分有限。并且不便于代码移植,毕竟STL在大部分代码中都有使用。
NDK支持哪几种C++运行库
Name | 解释 | 特征 |
---|---|---|
libstdc++ (default) | The default minimal system C++ runtime library. | N/A |
gabi++_static | The GAbi++ runtime (static). | C++ Exceptions and RTTI |
gabi++_shared | The GAbi++ runtime (shared). | C++ Exceptions and RTTI |
stlport_static | The STLport runtime (static). | C++ Exceptions and RTTI; Standard Library |
stlport_shared | The STLport runtime (shared). | C++ Exceptions and RTTI; Standard Library |
gnustl_static | The GNU STL (static). | C++ Exceptions and RTTI; Standard Library |
gnustl_shared | The GNU STL (shared). | C++ Exceptions and RTTI; Standard Library |
c++_static | The LLVM libc++ runtime (static). | C++ Exceptions and RTTI; Standard Library |
c++_shared | The LLVM libc++ runtime (shared). | C++ Exceptions and RTTI; Standard [Library] |
显然如果你要使用vector、map、string等,你必须指定一个支持Standard Library 的C++运行库。他们在ndk-bundle中对应的文件夹是:
\sources\cxx-stl\
。如何指定运行库 这里要说一下共享库和静态库的区别。共享库直观上的讲就是多个软件用一个库文件,因此内存里只会存在一份代码。而静态库就是各用各的。他们之间各有好处。这里如果使用
share
结尾的运行库,那么运行库就不会打包到你的so里,程序运行的时候会装载Android系统上自带的库。当然如果这台Android设备/system/libs
下没有这个库,那么程序就会崩溃。但个人认为最好还是使用共享库,因为这会减小生成so的大小。Android.mk中使用 给APP_STL标签指定对应的值(上表中的Name字段)即可。如果没有指定,即使用默认的
libstdc++
,这里需要注意一点,无论静态还是共享都只能指定一个运行库。//use gnustl_static
APP_STL := gnustl_static
//use gnustl_shared
APP_STL := gnustl_shared
【Android Studio NDK 入门教程(7)--被NDK支持的C++运行库】如果要使用特征中的
C++ Exceptions
则还需要显示指定CPPFLAG
:APP_CPPFLAGS += -fexceptions
如果要使用特征中的
RTTI
则还需要显示指定CPPFLAG
:APP_CPPFLAGS += -frtti
Gradle配置 在Gradle中
stl
标签等价于APP_STL
,cppFlags
标签等价于APP_CPPFLAGS
:stl "stlport_share"
cppFlags "-frtti"
//实验版gradle
cppFlags.add("-frtti")
关于使用静态还是共享库的官方建议
- Static Runtime
链接C++的静态库到多个二进制可能会导致意外的行为。例如,您可能会遇到:
- 一个库分配的内存,而在其他释放,造成内存泄漏或堆损坏。
- 在
libfoo
抛出的异常而在libbar
中捕获,这将引起你的应用崩溃。 std::cout
的缓冲可能不会正确的工作。
- Shared runtimes
如果您的应用程序针对一个版本的Android早于Android 4.3的(API 18),并使用给定的C++运行时的共享库,必须依赖于它的任何其他库之前加载共享库。
例如, 一个应用可能有如下库:
libfoo.so
libbar.so //在libfoo中使用
libstlport_shared.so //在libfoo和libbar中使用
//你必须根据其依赖关系对它们进行加载
static {
System.loadLibrary("stlport_shared");
System.loadLibrary("bar");
System.loadLibrary("foo");
}
提示: 调用
System.loadLibrary()
不要使用库的后缀,即去掉.so
后缀。扩展知识
- Android 稳定的NDK系统API
- 如何使用预编译库
推荐阅读
- android第三方框架(五)ButterKnife
- Android中的AES加密-下
- 带有Hilt的Android上的依赖注入
- android|android studio中ndk的使用
- Android事件传递源码分析
- RxJava|RxJava 在Android项目中的使用(一)
- Android7.0|Android7.0 第三方应用无法访问私有库
- 深入理解|深入理解 Android 9.0 Crash 机制(二)
- android防止连续点击的简单实现(kotlin)
- Android|Android install 多个设备时指定设备