您的位置:首页 > 编程语言 > C语言/C++

Android Studio NDK 入门教程(7)--被NDK支持的C++运行库

2016-09-02 15:05 573 查看

概述

Android 默认使用的是最小系统c++运行库,功能十分有限。并且不便于代码移植,毕竟STL在大部分代码中都有使用。

NDK支持哪几种C++运行库

Name解释特征
libstdc++ (default)The default minimal system C++ runtime library.N/A
gabi++_staticThe GAbi++ runtime (static).C++ Exceptions and RTTI
gabi++_sharedThe GAbi++ runtime (shared).C++ Exceptions and RTTI
stlport_staticThe STLport runtime (static).C++ Exceptions and RTTI; Standard Library
stlport_sharedThe STLport runtime (shared).C++ Exceptions and RTTI; Standard Library
gnustl_staticThe GNU STL (static).C++ Exceptions and RTTI; Standard Library
gnustl_sharedThe GNU STL (shared).C++ Exceptions and RTTI; Standard Library
c++_staticThe LLVM libc++ runtime (static).C++ Exceptions and RTTI; Standard Library
c++_sharedThe LLVM libc++ runtime (shared).C++ Exceptions and RTTI; Standard [Library]
来源:Android NDK Developer

显然如果你要使用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


如果要使用特征中的
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
的缓冲可能不会正确的工作。

此外,如果您链接两个共享库或一个共享库并针对相同的静态运行环境,那么最终每个二进制文件都将会存在一份静态库的拷贝。具有运行时代码多个实例是因为某些全局变量的重复运行期使用或内部提供的问题。这个问题并不适用于包括单个共享库的一个项目。例如,您可以针对性链接stlport_static,并期待您的应用程序正确运行。如果你的项目需要多个共享库模块,我们建议您使用C++运行时的共享库。

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

如何使用预编译库
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: