NDK 文档并不完全准确,至少目前不准确。事实上,它在使用预构建工具链时声明“您将无法使用任何 C++ STL(STLport 或 GNU libstdc++)。”,但这已经过时了。我使用包含相同的错误创建了一个小型 hello world 程序。但是,无需创建自己的工具链即可解决此问题,如果您不想在配置过程中再添加一个步骤,并且允许您始终使用最新的 SDK 平台,而无需每次都创建新的工具链,那就太好了。
NDK 附带了几个版本的标准 C++ 库的源代码:GAbi++、STLport 和 GNU STL。每种风格都带有预构建的共享库和静态库。我下面的示例将使用 stlport。
要在其安装位置使用独立工具链,您可以执行以下操作:export CXX='$NDK_ROOT/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/bin/arm-linux-androideabi- g++ --sysroot="$NDK_ROOT/platforms/android-19/arch-arm"'
例如,这会将您的 CXX 编译器设置为使用 SDK 平台级别 19 在 OS X 系统上编译 ARM。您可能已经知道这一点。此外,如果您使用它,您可能希望导出您的 CC、CPP、LD、AR 和 RANLIB。我还亲自为 READELF 创建了一个 envar。
要添加对 C++ 库的支持,您可以执行以下操作: $CXX helloworld.cpp -I$NDK_ROOT/sources/cxx-stl/stlport/stlport -L$NDK_ROOT/sources/cxx-stl/stlport/libs/armeabi - lstlport_shared
请注意,这将链接 libstlport_shared.so 现在在运行时需要它,因此您可能需要向上述命令添加相对路径以支持该路径,具体取决于您的 APK 结构。如果您只想测试这个简单的案例,您可以在模拟器上运行它,如下所示:
adb push a.out /data
adb push $NDK_ROOT/sources/cxx-stl/stlport/libs/armeabi/libstlport_shared.so /data
adb shell
# su
# cd /data
# chmod 777 a.out
# ./a.out
为了摆脱处理共享库路径的麻烦,您还可以通过将“-lstlport_shared”更改为“-lstlport_static”来静态链接 C++ 库。这样做会产生一些后果,如 NDK 开发指南中所述。最大的问题是由于静态库在多个位置链接,导致: - 在一个库中分配的内存并在另一个库中释放会泄漏甚至损坏堆。- 在 libfoo.so 中引发的异常不能在 libbar.so 中捕获(并且可能会简单地使程序崩溃)。- std::cout 的缓冲不能正常工作
还包括一个有用的工具,即 readelf 工具,可以查看您的程序具有哪些依赖项。
要查看您的程序需要哪些其他共享库,您可以运行以下命令: $NDK_ROOT/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-readelf -a a.out | 需要 grep
其他很酷的标准工具: addr2line - 将堆栈跟踪地址转换为代码行 nm - 显示符号表 objdump - 显示对象的信息