在ios上使用来自框架的boost :: filesysystem路径

Hal*_*l J 7 boost ios

我一直在使用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);
}
Run Code Online (Sandbox Code Playgroud)

当路径对象被销毁时会导致EXC_BAD_ACCESS(问题发生在path的basic_string成员的析构函数中).有没有其他人遇到这个问题?所有内容都使用相同的SDK构建,并且可见性设置在测试项目和框架上是相同的.Inside :: exists,在路径上调用的唯一函数是.c_str(),我可以在我的代码中调用它没有问题.它将.c_str()的结果传递给:: stat,我也可以成功调用它.这似乎是某种运行时不匹配.有任何想法吗?

小智 7

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
   ;
Run Code Online (Sandbox Code Playgroud)

到目前为止,这似乎运作良好; 我没有经过足够的测试来完全确保自己没有与提升相关的任何问题,但这比将新的iPhone项目带回llvm-gcc更容易.