2012-02-01 10 views
7

ho usato Boost come una struttura costruita da uno script di Pete Goodliffe per un bel po 'di tempo. Funziona alla grande. Recentemente ho colpito un problema che può essere riprodotto da far cadere il seguente codice nel viewDidLoad di un controller della vista in una nuova altrimenti marchio progetto XCode:usando boost :: percorso filesysystem dal quadro sul ios

#include "boost/filesystem/path.hpp" 
#include "boost/filesystem/operations.hpp" 


- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    boost::filesystem::path path("/var/mobile/Applications/.../Documents/somefile.txt"); 
    bool b = boost::filesystem::exists(path); 
} 

Questo si traduce in EXC_BAD_ACCESS quando l'oggetto percorso viene distrutto (il problema si verifica nel distruttore del membro basic_string del percorso). Qualcun altro ha incontrato questo problema? Tutto è stato creato con lo stesso SDK e le impostazioni di visibilità sono le stesse su progetto di test e framework. Inside :: exists, l'unica funzione chiamata on path è .c_str(), che posso chiamare nel mio codice senza problemi. Passa il risultato di .c_str() a :: stat, che posso anche chiamare con successo. Sembra una mancata corrispondenza di runtime di qualche tipo. Qualche idea?

risposta

7

Lo script di Pete Goodliffe incrementa l'utilizzo di gcc, che nell'attuale SDK è llvm-gcc. Il sistema Boost.Build rileva gcc e abilita un set di macro di visibilità per determinate cose, in particolare alcune delle eccezioni utilizzate dalla libreria del filesystem quando GCC è in uso. Per impostazione predefinita, le applicazioni iOS create utilizzando l'SDK corrente utilizzeranno clang. Le intestazioni di configurazione di boost rilevano anche clang quando è in uso, e questi macro di visibilità non sono configurati allo stesso modo. Questo porta ad alcuni avvertimenti del linker quando usi clang per costruire la tua applicazione contro boost, ma usa una libreria boost costruita con gcc, ad es. sulla visibilità di vtable e destructor per le classi di eccezioni in questione. Quando la tua stringa viene passata in una di queste classi, come è probabile che succeda quando chiami filesystem :: exists(), vedi un crash nel distruttore.

Per questo specifico esempio, è possibile risolvere il problema creando boost con visibility = default, ma è improbabile che funzioni bene per applicazioni non banali. Finora, sembra che la soluzione migliore sia impostare il compilatore su clang ++ in modo da avere le stesse impostazioni di visibilità in vigore per queste classi quando si costruisce la libreria come si fa quando si costruisce l'applicazione. Ecco la user-config.jam che sto usando con (la mia versione modificata di) quello script e Xcode 4.2.x. Tieni presente che dovrai sostituire $ IPHONE_SDKVERSION, ARM_DEV_DIR e SIM_DEV_DIR se non li imposti nello script. Per me, che sono 5.0 e le directory bin di iPhone e simulatore SDK, rispettivamente:

using darwin : $IPHONE_SDKVERSION~iphone 
    : ${ARM_DEV_DIR}clang++ 
    : <striper> 
    <compileflags>"-arch armv7 -fvisibility=hidden -fvisibility-inlines-hidden $EXTRA_CPPFLAGS" 
    : <architecture>arm <target-os>iphone 
    ; 
using darwin : $IPHONE_SDKVERSION~iphonesim 
    : ${SIM_DEV_DIR}clang++ 
    : <striper> 
    <compileflags>"-arch i386 -fvisibility=hidden -fvisibility-inlines-hidden $EXTRA_CPPFLAGS" 
    : <architecture>x86 <target-os>iphone 
    ; 

Finora, che sembra funzionare bene; Non ho provato abbastanza per assicurarmi che non ci siano problemi di clang con boost, ma questo sembra più facile che portare a llvm-gcc nuovi progetti per iPhone.

Problemi correlati