Android NDK 知识系列(五)
16lz
2021-01-23
基础知识:
AndroidPlatform提供一个非常小的C++runtime支持库(/system/lib/libstdc++)和头文件。
但此SystemC++库支持非常有限,不支持以下:
-StandardC++Librarysupport(exceptafewtrivialheaders).
-C++exceptionssupport
-RTTIsupport
但Android也提供几个其它的选择。可以通过Application.mk中APP_STL作设置。
设置选项有如下选择:
system->UsethedefaultminimalsystemC++runtimelibrary.
gabi++_static->UsetheGAbi++runtimeasastaticlibrary.
gabi++_shared->UsetheGAbi++runtimeasasharedlibrary.
stlport_static->UsetheSTLportruntimeasastaticlibrary.
stlport_shared->UsetheSTLportruntimeasasharedlibrary.
gnustl_static->UsetheGNUSTLasastaticlibrary.
gnustl_shared->UsetheGNUSTLasasharedlibrary.
当APP_STL没有设置时,则缺省使用system的这个。
以上几种C++库能力集对:C++Exceptions,C++RTTI,StandardLibrary支持分别如下:
system no no no
gabi++ no yes no
stlport no yes yes
gnustl yes yes yes
1.各Runtime简介:
1.1:SystemRuntime:
Android提供的C++ Runtime,它只提供几个非常少的C++ 标准头文件。如果使用它,则应用程序二进制自动的链接此Android系统libstdc++。
提供的头文件只有以下这些:
cassert cctype cerrno cfloat climits cmath csetjmp csignal cstddef cstdint cstdio cstdlib cstring ctime cwchar new stl_pair.h typeinfo utility
不支持:std::stringorstd::vector.
1.2:GAbi++runtime:
这是另一个小的C++runtime,与SystemC++提供同样多的头文件。但它支持RTTI。现在已经很少用了。
1.3:STLportruntime:
STLport(http://www.stlport.org)的Android移植版。提供完整的C++标准库头文件,支持RTTI,但不支持EXCEPTIONS.(不支持异常很麻烦,就需要改不少代码)
静态动态均支持:
APP_STL:=stlport_shared
APP_STL:=stlport_static
1.4:GNUSTLruntime:
GNU标准的C++library.支持更多特性。库名叫:libgnustl_shared.so,而不是其它平台通常的:libstdC++.so
2.其它事项:
2.1:C++Exceptions:
自从NDKr5,NDKToolchain就支持异常,可是,所有C++代码都缺省使用-fno-exceptions编译,为的是向前兼容。
为了EnableC++Exceptions,可以作如下动作:
在Android.mk中:
LOCAL_CPP_FEATURES += exceptions (推荐)
或者:
LOCAL_CPPFLAGS += -fexceptions
或者在Application.mk中:
APP_CPPFLAGS += -fexceptions
2.2:RTTIsupport:
与异常类似,自动NDKr5,NDKToolChain就支持RTTI,但在缺省情况下都是用-fno-rtti来编译C++代码。
如果想EnableRTTI;
在Andriod.mk中:
LOCAL_CPP_FEATURES += rtti (推荐)
或者
LOCAL_CPPFLAGS += -frtti
或者在:Application.mk:
APP_CPPFLAGS += -frtti
2.3:Staticruntimes:
当工程只有一个动态库用到C++library.则其使用静态C++库没有问题。
但当工程中有多个动态库用到C++library(或其它静态库)时,则问题来了,每个动态库会包含静态库进去。这就有问题了,因为在内存中,就有多份COPY,那全局变量等都会有问题。
所以,当工程中多个动态库链接C++library时,不要使用静态C++库方式。
2.4:Sharedruntimes:
在使用动态库时,则需要确保C++动态库在其它库之前被Load到内存。
例如:
libfoo.so
libbar.so which is used by libfoo.so
libstlport_shared.so, used by both libfoo and libbar
则:
static
{
System.loadLibrary("gnustl_shared");
System.loadLibrary("bar");
System.loadLibrary("foo");
}
有一点需要注意:
因为C++程序调用xxx-xxx-g++编译,所以使用C++命名规范命名符号,这样,JavaJNI程序就找不到对应符号了。
所以需要添加:
#ifdef __cplusplus
extern "C"{
#endif
function声明。
#ifdef __cplusplus
}
#endif
3.对std::wstring支持:
在NDKR7中,如果不做处理,则std::wstring会报未定义。
于是查找之:
在:android-ndk-r7/sources/cxx-stl/gnu-libstdc++/include/bits/stringfwd.h
#ifdef _GLIBCXX_USE_WCHAR_T
template<>structchar_traits<wchar_t>;
typedefbasic_string<wchar_t>wstring;
#endif
所以,如果想要支持wstring,则需要定义 _GLIBCXX_USE_WCHAR_T
于是:在Android.mk中,
在LOCAL_CXXFLAGS,LOCAL_CFLAGS中添加:
-D_GLIBCXX_USE_WCHAR_T
即可支持wstring.
更新:wstring在R7C版本中,编译虽然没有问题,但链接时会报错。
只有替换了NDK R8之后,才真正没有问题了。
Android C++库支持有些不妥之处,例如:
在多Thread中使用cout,或者cout 与printf混和使用,会造成程序卡死。
注意:此处NDK版本为NDKR7C.(不同NDK版本,ndk-build所产生的Makefile并不完全相同)
更多相关文章
- Smalidea+IntelliJ IDEA/Android Studio动态调试安卓app教程
- 使用valgrind检测Android native程序的内存
- Android游戏开发实践指南(华章程序员书库)
- Android 程序获取、设置铃声和音量
- Android 程序获取、设置铃声、音量、静音、扬声器
- [置顶] Android系统安全之旅 第1章 编译Android程序的方法
- Android 动态注册广播
- android 可执行程序终于可以在nxp8473--cortex-a9平台运行