Как использовать библиотеку boost (включая shared_ptr) с Android NDK и STLport

Это скорее ответ, чем вопрос, потому что я понял это, по крайней мере, до чисто компиляции библиотеки. Основной проблемой для меня было заставить работать shared_ptr.

Состав:

Boost v. 1.45.0

Версия STLport на http://www.anddev.org/viewtopic.php?p=29939.

Версия r4b для NDK.

Направления:

В вашем файле Android.mk добавьте:

LOCAL_CFLAGS += -DBOOST_EXCEPTION_DISABLE -D_STLP_NO_EXCEPTIONS -DOS_ANDROID -D_STLP_USE_SIMPLE_NODE_ALLOC

Удалите вызов __stl_throw_length_error по строке 613 из stlport/stl/_string.h. Вы можете использовать _STLP_NO_EXCEPTIONS, если хотите.

Измените boost/boost/smart_ptr/shared_ptr.hpp после строки 261, чтобы избавиться от вызова boost:: throw_exception в конструкторе shared_ptr. Я использовал #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. Скомпилируйте источник и добавьте его в свою библиотеку.

Ответ 1

Оказалось, что этот подход не совсем работает при компиляции отлаживаемой библиотеки. Библиотека выпуска скомпилирована с -O2, которая оптимизирует некоторые неточности, но библиотека отладки выполняется с -O0, что выявляет некоторые дополнительные проблемы. Кроме того, я не был слишком доволен необходимостью редактировать файлы форсирования. Поэтому с некоторым дополнительным исследованием я придумал следующее решение.

Во-первых, не редактируйте файлы форсирования. Вместо этого добавьте следующее в заголовок в пространстве имен std:

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

Затем добавьте следующее в исходный файл:

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

Теперь это компилируется и добавляется в приложение даже с андроидом: debuggable = "true" в AndroidManifest.xml. Он не запускается в эмуляторе, но тогда он не делал этого, прежде чем я включил эту библиотеку.

Ответ 2

Примечательно, что NDK r5 поставляется с STLport и GNU STL, и поэтому теперь уже не понадобятся хаки, поскольку есть поддержка STL b) поддержка исключений в компиляторе NDK С++.

Ответ 3

Другим обходным решением для shared_ptr является, в частности, использование boost:: intrusive_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/