我一直在使用Boost作为Pete Goodliffe脚本构建的框架已有一段时间了.效果很好.最近我遇到了一个问题,可以通过将以下代码放入另一个全新的XCode项目中的视图控制器的viewDidLoad中来重现:
#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); }
当路径对象被销毁时会导致EXC_BAD_ACCESS(问题发生在path的basic_string成员的析构函数中).有没有其他人遇到这个问题?所有内容都使用相同的SDK构建,并且可见性设置在测试项目和框架上是相同的. Inside :: exists,在路径上调用的唯一函数是.c_str(),我可以在我的代码中调用它没有问题.它将.c_str()的结果传递给:: stat,我也可以成功调用它.这似乎是某种运行时不匹配.有任何想法吗?
解决方法
Pete Goodliffe的脚本使用gcc构建了boost,在当前的SDK中是llvm-gcc. Boost.Build系统检测gcc并为某些事物启用一组可见性宏,特别是当使用GCC时文件系统库使用的一些异常宏.默认情况下,使用当前SDK构建的iOS应用程序将使用clang. boost配置标头还会在使用时检测clang,并且这些可见性宏的配置方式不同.当您使用clang来构建针对boost的应用程序但使用使用gcc构建的boost库时,这会导致一些链接器警告,例如关于有问题的异常类的vtable和析构函数可见性.当你的字符串被传递到这些类中的一个时,当你调用filesystem :: exists()时可能会发生这种情况,你会在析构函数中看到崩溃.
对于此特定示例,您可以通过使用visibility = default构建boost来解决此问题,但这不太适用于非平凡的应用程序.到目前为止,最好的办法是将编译器设置为clang,以便在构建库时为这些类生成相同的可见性设置,就像构建应用程序时一样.这是我正在使用的user-config.jam(我的修改版本)该脚本和Xcode 4.2.x.请注意,如果您没有在脚本中设置它们,则需要替换$IPHONE_SDKVERSION,ARM_DEV_DIR和SIM_DEV_DIR.对我来说,它们分别是5.0和iphone和模拟器SDK的bin目录:
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 ;
到目前为止,这似乎运作良好;我没有经过足够的测试来完全确保自己没有与提升相关的任何问题,但这比将新的iPhone项目带回llvm-gcc更容易.