使用libstdc ++编译的库和clang ++ -stdlib = libc ++

我在Mac OS X(10.8.2)下使用C ++,最近我想出了使用C ++ 11特性的必要性,这些特性可以通过使用libc ++ stdlib的clang ++编译器获得。 不过,我还需要使用一些遗留库,编译并链接到libstdc ++(来自MacPorts)。

在这样做的时候,我得到了链接错误,因为使用std::string的遗留库的头文件需要根据std::__1::basic_string (即std::string的libc ++实现)而不是std::basic_string实现。

有没有办法在开发中混合两个库(例如,使用一些预处理器标志?)

你所看到的是使用内联命名空间来实现ABI版本控制。

那意味着什么:

libstdc ++ std::string是与libc ++ std::string不同的数据结构。 前者是参考计数devise,而后者则不是。 尽pipe它们是API兼容的,但它们不是ABI兼容的。 这意味着如果你用libstdc ++构造一个std::string ,然后把它传给其他与libc ++链接的代码,接收代码会认为它有一个libc ++ std::string 。 也就是说,接收者不会有任何线索应该增加或减less引用计数。

没有内联命名空间,结果将是运行时错误。 最好的你可以希望是一个崩溃。 使用内联命名空间,该运行时错误被转换为链接时间错误。

对于程序员来说,libstdc ++ std::string和libc ++ std::string看起来像是相同的types。 但是对于连接器来说,它们看起来像完全不同的types(线索是std::__1命名空间)。 而链接器的观点是正确的。 他们完全不同的types。

所以是的,你可以操纵一些预处理器标志来获得链接。 但是,那么你将有一个时间debugging结果运行时错误的恶魔。

唯一的办法做你想做的是使这些dylib之间的接口不涉及std::types,如string 。 例如,你可以传递char数组。 您甚至可以将内存所有权从libstdc ++ – 链接代码转移到libc ++ – 链接代码,反之亦然(它们都将放到同一个malloc池中)。