Как использовать библиотеку 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/