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

Android NDK学习 <五> C++ 支持

2013-08-09 15:27 435 查看
http://blog.sina.com.cn/s/blog_602f877001014qe5.html

0.基础知识:

AndroidPlatform提供一个非常小的C++runtime支持库(/system/lib/libstdc++)和头文件。

但此SystemC++库支持非常有限,不支持以下:

-StandardC++Librarysupport(exceptafewtrivialheaders).
-C++exceptionssupport
-RTTIsupport

但Android也提供几个其它的选择。可以通过Application.mk中APP_STL作设置(见AndroidNDK学习<四>Application.mk简介)。

设置选项有如下选择:

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支持分别如下:


systemnonono
gabi++noyesno
stlportnoyesyes
gnustlyesyesyes

1.各Runtime简介1.1:SystemRuntime:
Android提供的C++Runtime,它只提供几个非常少的C++标准头文件。如果使用它,则应用程序二进制自动的链接此Android系统libstdc++。

提供的头文件只有以下这些:

cassertcctypecerrnocfloatclimitscmathcsetjmpcsignalcstddefcstdintcstdiocstdlibcstringctimecwcharnewstl_pair.htypeinfoutility

不支持: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.sowhichisusedbylibfoo.so
libstlport_shared.so,usedbybothlibfooandlibbar

则:

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会报未定义。
于是Sam查找之:
在: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.

更新:Sam发现,wstring在R7C版本中,编译虽然没有问题,但链接时会报错。

只有替换了NDKR8之后,才真正没有问题了。



AndroidC++库支持有些不妥之处,例如:

在多Thread中使用cout,或者cout与printf混和使用,会造成程序卡死。


注意:此处NDK版本为NDKR7C.(不同NDK版本,ndk-build所产生的Makefile并不完全相同[b])[/b]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: