2010-12-03 8 views
57

Dies ist mehr eine Antwort als eine Frage, denn ich habe es herausgefunden, zumindest so sauber wie die Bibliothek kompilieren. Das Hauptproblem für mich war, dass shared_ptr funktioniert.So verwenden Sie die Boost-Bibliothek (einschließlich shared_ptr) mit dem Android NDK und STLport

Zutaten:

Boost-v 1.45.0

Die Version von STLport bei http://www.anddev.org/viewtopic.php?p=29939..

Version r4b des NDK.

Anfahrt:

In Ihrer Android.mk Datei hinzufügen:

LOCAL_CFLAGS += -DBOOST_EXCEPTION_DISABLE -D_STLP_NO_EXCEPTIONS -DOS_ANDROID -D_STLP_USE_SIMPLE_NODE_ALLOC 

den Anruf entfernen in Zeile 613 von STLport/stl/_string.h __stl_throw_length_error. Sie können _STLP_NO_EXCEPTIONS verwenden, wenn Sie möchten.

Bearbeiten Sie boost/boost/smart_ptr/shared_ptr.hpp nach Zeile 261, um den Aufruf von boost :: throw_exception im shared_ptr -Konstruktor loszuwerden. Ich habe #ifndef BOOST_EXCEPTION_DISABLE um den gesamten Körper der Methode verwendet. (Aber sehen Sie die Antwort unten.)

Als nächstes müssen Sie einige fehlende Teile liefern. Erstellen Sie eine Headerdatei mit folgendem:

#ifdef OS_ANDROID 

#include <exception> 

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

#endif 

und eine Quelldatei mit einer abgespeckten Ausnahmeklasse bad_alloc zu unterstützen:

#ifdef OS_ANDROID 

#include <exception> 

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

#endif 

Fügen Sie den Header, wo Sie mit boost/shared_ptr.hpp . Kompilieren Sie die Quelle und fügen Sie sie Ihrer Bibliothek hinzu.

+9

Um diese Frage zu verhindern, immer offen zu sein, wäre es sehr cool, wenn Sie diesen Beitrag als Frage umformulieren könnten und es dann selbst beantworten, wie sie in der [FAQ] (http vorgeschlagen: // stackoverflow.com/faq#ask). – dennycrane

+1

Danke für das Teilen, was Sie gelernt haben! Ich bin mir sicher, dass dies für viele hilfreich ist. –

+0

Dennycrane, ich experimentiere immer noch mit diesem Ansatz, also möchte ich es offen lassen, falls es mehr hinzuzufügen gibt. Wenn ich eine sauber laufende Bibliothek bekomme, melde ich das und schließe die Frage mit einer Antwort. –

Antwort

39

Es hat sich herausgestellt, dass dieser Ansatz beim Kompilieren einer debuggierbaren Bibliothek nicht vollständig funktioniert. Die Release-Bibliothek wird mit -O2 kompiliert, was einige Fehler beseitigt, aber die Debug-Bibliothek wird mit -O0 gemacht, was einige zusätzliche Probleme aufzeigt. Außerdem war ich nicht gerade glücklich darüber, die Boost-Dateien bearbeiten zu müssen. Mit einigen zusätzlichen Studien habe ich die folgende Lösung gefunden.

Bearbeiten Sie zunächst keine der Boost-Dateien. Stattdessen fügen Sie den folgenden in den Header im std-Namespace:

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

als Nächstes Folgendes an der Quelldatei hinzufügen:

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

Das jetzt kompiliert und Links in die Anwendung auch mit Android: debug =“ wahr "in AndroidManifest.xml. Es läuft nicht im Emulator, aber das hat es auch nicht gemacht, bevor ich diese Bibliothek mit einschloss.

+2

Gab dir so viele Upvotes wie ich konnte. Habe ungefähr einen ganzen Tag damit verbracht, daran zu arbeiten, und das zu finden, hat enorm geholfen. –

+1

Und da Sie tatsächlich Ihre eigene Frage wie oben vorgeschlagen beantwortet haben, verdienen Sie eine weitere Verbesserung. Ich wünschte, dass mehr Leute (einschließlich, leider, selbst) daran denken würden, ihre hart erkämpften Lösungen hier zu veröffentlichen, ohne dass jemand anders sie darum bittet. –

+0

Verdammt, danke! –

3

Bemerkenswert, NDK r5 kommt mit STLport und der GNU STL, und so werden die Hacks hier nicht mehr notwendig sein, jetzt da es a) STL-Unterstützung b) Ausnahmeunterstützung im NDK C++ - Compiler gibt.

+0

Ihre Punkte a und b gelten einzeln, aber nicht in Kombination (siehe WARNING in Abschnitt III von CPLUSPLUS-SUPPORT.html in der Dokumentation zu nkd.) Daher benötigen Sie immer noch std :: bad_alloc, std :: bad_cast und boost :: throw_exception hacks habe ich besprochen. –

+0

Es ist merkwürdig. Die oben zitierte Dokumentation bezieht sich überhaupt nicht auf die GNU STL, außer dass "Full GNU libstdC++ support" ein Zukunftsplan ist. Aber da ist es in der NDK unter Quellen/cxx-stl zusammen mit ihrem minimalen System und stlport. Hast du es geschafft, es zur Arbeit zu bringen? Ich stelle eine fortlaufende Diskussion zu diesem Thema unter http://groups.google.com/group/android-ndk/browse_thread/thread/da175a5d6b8b7956 fest. –

+0

Es scheint auf der NDK-Seite unter http://developer.android.com/sdk/ndk/index.html und nicht in der Dokumentation erwähnt zu werden. quote "Stellt eine standardmäßige C++ - STL-Implementierung (basierend auf STLport) als Hilfsmodul bereit. Sie kann entweder als statische oder gemeinsam genutzte Bibliothek verwendet werden (Details und Verwendungsbeispiele finden Sie in sources/android/stlport/README). Vordefinierte Binärdateien für STLport (statisch oder gemeinsam) und GNU libstdC++ (nur statisch) "Scheint so, als ob libstdC++ mit Ausnahmen und RTTI funktioniert. – grrussel

1

Eine andere Problemumgehung für shared_ptr insbesondere ist, boost :: intrusive_ptr stattdessen zu verwenden. Das ist nicht immer möglich, hat aber für meine Situation funktioniert.

+1

Sie können auch extrahieren shared_ptr von shared_ptr_nmt.hpp ziemlich einfach, es ist eine vereinfachte Version. – Chris

0

Die aktuelle Version von Android NDK (r9) unterstützt jetzt Ausnahmen.

Die Möglichkeiten der verschiedenen Laufzeiten variieren. Siehe diese Tabelle:

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

stlport kann in Nicht-GPL-Binärdateien verwendet werden. Es wird immer noch als experimentell markiert, aber Sie können es mit clang und gcc verwenden.

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

Verwandte Themen