How to use the boost library (including shared_ptr) with the Android NDK and STLport

C++BoostAndroid NdkStlport

C++ Problem Overview


This is more of an answer than a question, because I've figured it out, at least as far as cleanly compiling the library. The main issue for me was to get shared_ptr working.

Ingredients:

Boost v. 1.45.0

The version of STLport at http://www.anddev.org/viewtopic.php?p=29939.

Version r4b of the NDK.

Directions:

In your Android.mk file add:

LOCAL_CFLAGS += -DBOOST_EXCEPTION_DISABLE -D_STLP_NO_EXCEPTIONS -DOS_ANDROID -D_STLP_USE_SIMPLE_NODE_ALLOC

Remove the call to __stl_throw_length_error at line 613 of stlport/stl/_string.h. You can use _STLP_NO_EXCEPTIONS if you like.

Edit boost/boost/smart_ptr/shared_ptr.hpp after line 261 to get rid of the call to boost::throw_exception in the shared_ptr constructor. I used #ifndef BOOST_EXCEPTION_DISABLE around the entire body of the method. (But see the answer below.)

Next you need to supply some missing pieces. Create a header file with the following:

#ifdef OS_ANDROID

#include <exception>

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

#endif

and a source file with a stripped-down exception class to support bad_alloc:

#ifdef OS_ANDROID

#include <exception>

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

#endif

Include the header wherever you're including boost/shared_ptr.hpp. Compile the source and add it to your library.

C++ Solutions


Solution 1 - C++

It turned out that this approach does not entirely work when compiling a debuggable library. The release library is compiled with -O2 which optimizes out some infelicities, but the debug library is done with -O0 which reveals some additional problems. Furthermore, I wasn't too happy about having to edit the boost files. So with some additional study, I've come up with the following solution.

First, don't edit any of the boost files. Instead add the following to the header within the std namespace:

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

Next add the following to the source file:

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

This now compiles and links into the application even with android:debuggable="true" in AndroidManifest.xml. It doesn't run in the emulator, but then it wasn't doing that before I included this library either.

Solution 2 - C++

Notably, NDK r5 comes with STLport, and the GNU STL, and so the hacks here are no longer going to be necessary now that there is a) STL support b) exception support in the NDK C++ compiler.

Solution 3 - C++

Another workaround for shared_ptr in particular is to use boost::intrusive_ptr instead. This is not always possible, but worked for my situation.

Solution 4 - C++

The current version of Android NDK (r9) now supports exceptions.

The capabilities of the various runtimes vary. See this table:

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

stlport can get used in non-GPL binarys. It's still flagged as experimantal, but you can use it with clang and gcc.

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGamma DraconisView Question on Stackoverflow
Solution 1 - C++Gamma DraconisView Answer on Stackoverflow
Solution 2 - C++grrusselView Answer on Stackoverflow
Solution 3 - C++Martin StoneView Answer on Stackoverflow
Solution 4 - C++sweisgerber.devView Answer on Stackoverflow