【问题标题】:How to use the boost library (including shared_ptr) with the Android NDK and STLport如何在 Android NDK 和 STLport 中使用 boost 库(包括 shared_ptr)
【发布时间】:2011-05-19 19:54:38
【问题描述】:

这更像是一个答案而不是一个问题,因为我已经弄清楚了,至少就干净地编译库而言。我的主要问题是让 shared_ptr 工作。

成分:

Boost v. 1.45.0

http://www.anddev.org/viewtopic.php?p=29939 上的 STLport 版本。

NDK 版本 r4b。

路线:

在您的 Android.mk 文件中添加:

LOCAL_CFLAGS += -DBOOST_EXCEPTION_DISABLE -D_STLP_NO_EXCEPTIONS -DOS_ANDROID -D_STLP_USE_SIMPLE_NODE_ALLOC

在 stlport/stl/_string.h 的第 613 行删除对 __stl_throw_length_error 的调用。如果您愿意,可以使用 _STLP_NO_EXCEPTIONS。

在第 261 行之后编辑 boost/boost/smart_ptr/shared_ptr.hpp 以摆脱 shared_ptr 构造函数中对 boost::throw_exception 的调用。我在方法的整个主体周围使用了#ifndef BOOST_EXCEPTION_DISABLE。 (但请参阅下面的答案。)

接下来您需要提供一些缺失的部分。使用以下内容创建头文件:

#ifdef OS_ANDROID

#include <exception>

namespace std
{
    struct bad_alloc : public exception { bad_alloc operator()(){}};
}

#endif

以及带有简化异常类以支持 bad_alloc 的源文件:

#ifdef OS_ANDROID

#include <exception>

namespace std
{
    exception::exception() {}
    exception::~exception() {}
    const char* exception::what() const {}
}

#endif

在包含 boost/shared_ptr.hpp 的任何地方都包含标题。编译源代码并将其添加到您的库中。

【问题讨论】:

  • 为了让这个问题永远不会被打开,如果您可以按照FAQ 的建议将这篇文章改写为一个问题然后自己回答,那将是非常酷的。
  • 感谢您分享您所学到的知识!我相信这对很多人都有帮助。
  • Dennycrane,我仍在尝试这种方法,所以我想让它保持开放状态,以防有更多内容需要添加。当我得到一个运行良好的库时,我会报告它并以答案结束问题。
  • 我同意@dennycrane 的观点,认为未来会更好,但更重要的是,您花时间以任何格式发布此有用的 SO 指南。我已经发现它很有帮助,我什至没有机会阅读它;简单地知道这是可能的将极大地帮助我设计我当前的项目。感谢您为我和许多其他人节省了以与您相同的方式找到答案的时间,无需任何问题提示您。

标签: c++ boost android-ndk stlport


【解决方案1】:

事实证明,这种方法在编译可调试库时并不完全有效。发布库是用 -O2 编译的,它优化了一些不合理的地方,但调试库是用 -O0 完成的,它揭示了一些额外的问题。此外,我对不得不编辑 boost 文件不太满意。因此,通过一些额外的研究,我提出了以下解决方案。

首先,不要编辑任何 boost 文件。而是将以下内容添加到 std 命名空间内的标题中:

struct bad_cast : public exception {bad_cast operator()(){}};

接下来将以下内容添加到源文件中:

namespace boost
{
    void throw_exception(std::exception const&) {}
}

现在,即使在 AndroidManifest.xml 中使用 android:debuggable="true",它也会编译并链接到应用程序。它不在模拟器中运行,但在我包含这个库之前它也没有这样做。

【讨论】:

  • 尽可能多地给你点赞。花了大约 1 天的时间来解决这个问题,发现这很有帮助。
  • 而且由于您实际上已经按照上面的建议回答了您自己的问题,因此您值得再次投票。我希望更多的人(包括,不幸的是,包括我自己)想到在这里发布他们来之不易的解决方案,而无需其他人要求他们这样做。
【解决方案2】:

值得注意的是,NDK r5 带有 STLport 和 GNU STL,因此现在不再需要这里的 hack,因为在 NDK C++ 编译器中有 a) STL 支持 b) 异常支持。

【讨论】:

  • 您的点 a 和 b 单独为真,但不能组合为真(请参阅 nkd 文档中 CPLUSPLUS-SUPPORT.html 的第 III 节中的警告。)因此,您仍然需要标准: :bad_alloc、std::bad_cast 和 boost::throw_exception 黑客我讨论过。
  • 这很奇怪。我上面引用的文档根本没有提到 GNU STL,只是说“完整的 GNU libstdc++ 支持”是未来的计划。但它在 NDK 的 sources/cxx-stl 下,连同它们的最小系统和 stlport。你设法让它工作了吗?我注意到groups.google.com/group/android-ndk/browse_thread/thread/… 正在讨论这个问题。
  • 似乎在 developer.android.com/sdk/ndk/index.html 的 NDK 页面上提到了它,而不是在文档中。引用“提供默认的 C++ STL 实现(基于 STLport)作为辅助模块。它可以用作静态库或共享库(详细信息和使用示例在 source/android/stlport/README 中)。STLport 的预构建二进制文件(静态或共享)和 GNU libstdc++(仅限静态)”似乎 libstdc++ 适用于异常和 RTTI。
  • 我可以用它编译,但是库链接阶段很糟糕,有很多未定义的引用错误。我尝试了一个明确的 LOCAL_LDLIBS += -lstdc++ 但它没有帮助。你让 APP_STL := gnustl_static 工作了吗?
  • 是的,它对我有用 (tm)。我不需要显式添加 STL 的 ld 参数;对于我构建和使用的所有其他库,但不是 STL 本身。您可以使用 std::vector 或类似的方法在 hello world 中进行验证。
【解决方案3】:

另一个针对 shared_ptr 的解决方法是使用 boost::intrusive_ptr 代替。这并不总是可行的,但适用于我的情况。

【讨论】:

  • 您也可以很容易地从 shared_ptr_nmt.hpp 中提取 shared_ptr,这是一个简化版本。
【解决方案4】:

当前版本的 Android NDK (r9) 现在支持异常。

各种运行时的功能各不相同。见下表:

          C++       C++   Standard
          Exceptions  RTTI  Library
system    no           no        no
gabi++   yes          yes        no
stlport  yes          yes       yes
gnustl   yes          yes       yes

stlport 可以在非 GPL 二进制文件中使用。它仍被标记为实验性的,但您可以将其与 clang 和 gcc 一起使用。

http://developer.android.com/tools/sdk/ndk/

【讨论】:

    猜你喜欢
    • 2013-02-28
    • 2014-03-19
    • 1970-01-01
    • 2011-11-30
    • 1970-01-01
    • 2012-11-20
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多