2010-12-03 6 views
57

Esto es más una respuesta que una pregunta, porque lo he descubierto, al menos en cuanto a la compilación limpia de la biblioteca. El principal problema para mí fue trabajar con shared_ptr.Cómo usar la biblioteca de impulso (incluyendo shared_ptr) con Android NDK y STLport

Ingredientes:

Boost v 1.45.0

La versión de STLport en http://www.anddev.org/viewtopic.php?p=29939..

Versión r4b del NDK.

llegar:

En el archivo de complemento Android.mk:

LOCAL_CFLAGS += -DBOOST_EXCEPTION_DISABLE -D_STLP_NO_EXCEPTIONS -DOS_ANDROID -D_STLP_USE_SIMPLE_NODE_ALLOC 

quitar la llamada a __stl_throw_length_error en la línea 613 de STLport/STL/_string.h. Puede usar _STLP_NO_EXCEPTIONS si lo desea.

Edite boost/boost/smart_ptr/shared_ptr.hpp después de la línea 261 para deshacerse de la llamada a boost :: throw_exception en el constructor shared_ptr. Usé #ifndef BOOST_EXCEPTION_DISABLE en todo el cuerpo del método. (Pero vea la respuesta a continuación.)

A continuación debe proporcionar algunas piezas faltantes. Crear un archivo de cabecera con lo siguiente:

#ifdef OS_ANDROID 

#include <exception> 

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

#endif 

y un archivo fuente con una clase de excepción reducidos al mínimo, para apoyar bad_alloc:

#ifdef OS_ANDROID 

#include <exception> 

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

#endif 

Incluir el encabezado donde quiera que estés incluyendo realce/shared_ptr.hpp . Compila la fuente y agrégala a tu biblioteca.

+9

Para mantener esta cuestión de estar abierto siempre, sería muy bueno si se podría volver este post como una pregunta y luego responder por sí mismo, como lo sugiere el [FAQ] (http: // stackoverflow.com/faq#ask). – dennycrane

+1

¡Gracias por compartir lo que has aprendido! Estoy seguro de que esto es útil para muchos. –

+0

Dennycrane, todavía estoy experimentando con este enfoque, así que quiero dejarlo abierto un poco en caso de que haya más que agregar. Cuando obtengo una biblioteca que funciona limpiamente, informaré sobre eso y cerraré la pregunta con una respuesta. –

Respuesta

39

Resultó que este enfoque no funciona del todo al compilar una biblioteca depurada. La biblioteca de versiones está compilada con -O2 que optimiza algunas infelicidades, pero la biblioteca de depuración está hecha con -O0, lo que revela algunos problemas adicionales. Además, no estaba muy contento de tener que editar los archivos de impulso. Entonces, con un estudio adicional, he encontrado la siguiente solución.

Primero, no edite ninguno de los archivos de impulso. En lugar añada lo siguiente a la cabecera dentro del espacio de nombres std:

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

A continuación añadir lo siguiente al archivo de origen:

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

Esto ahora compila y enlaces en la aplicación, incluso con android: depurable =" verdadero "en AndroidManifest.xml. No se ejecuta en el emulador, pero tampoco estaba haciendo eso antes de incluir esta biblioteca.

+2

Te he dado todos los votos por votos que pude. Pasé cerca de 1 día completo trabajando en descifrar esto, y encontrar esto me ayudó enormemente. –

+1

Y dado que, de hecho, ha respondido a su propia pregunta como se sugirió anteriormente, se merece otro voto alternativo. Desearía que más gente (incluida, lamentablemente, yo mismo) pensara publicar sus soluciones difíciles aquí sin que nadie más se las pidiera. –

+0

¡Maldición, gracias! –

3

Cabe destacar que NDK r5 viene con STLport y GNU STL, por lo que los hacks aquí ya no serán necesarios ahora que hay un soporte de STL b) soporte de excepción en el compilador NDK C++.

+0

Sus puntos a y b son ciertos individualmente, pero no combinados (vea la ADVERTENCIA en la sección III de CPLUSPLUS-SUPPORT.html en la documentación de nkd). En consecuencia, aún necesitará el std :: bad_alloc, std :: bad_cast y boost :: throw_exception hacks que discutí. –

+0

Es extraño. La documentación que cité arriba no se refiere a la STL de GNU, excepto para decir que "soporte completo de GNU libstdC++" es un plan futuro. Pero ahí está en el NDK bajo sources/cxx-stl junto con su sistema mínimo y stlport. ¿Has logrado que funcione? Noto un debate en curso sobre el tema en http://groups.google.com/group/android-ndk/browse_thread/thread/da175a5d6b8b7956. –

+0

Parece ser mencionado en la página NDK en http://developer.android.com/sdk/ndk/index.html y no en los documentos. quote "Proporciona una implementación C++ STL predeterminada (basada en STLport) como módulo auxiliar. Se puede usar como biblioteca estática o compartida (los detalles y ejemplos de uso se encuentran en sources/android/stlport/README). Binarios preconstruidos para STLport (estático o compartido) y GNU libstdC++ (solo estático) "Parece que libstdC++ funciona con excepciones y RTTI. – grrussel

1

Otra solución para shared_ptr en particular es usar boost :: intrusive_ptr en su lugar. Esto no siempre es posible, pero funcionó para mi situación.

+1

También puede usar extract shared_ptr de shared_ptr_nmt.hpp bastante fácilmente, es una versión simplificada. – Chris

0

La versión actual de Android NDK (r9) ahora admite excepciones.

Las capacidades de los diversos tiempos de ejecución varían. Consulte esta tabla:

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

stlport se puede utilizar en binarios no GPL. Todavía está marcado como experimental, pero puedes usarlo con clang y gcc.

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

Cuestiones relacionadas