使用libstdc++;使用clang+编译的库+-stdlib=libc++; 我在C++操作系统下工作,最近我提出了使用C++ 11的功能,这些功能是通过使用LIbC++STDLIB的CLAN+++编译器提供的。 但是,我还需要使用一些针对libstdc++编译和链接的遗留库(来自MacPorts)

使用libstdc++;使用clang+编译的库+-stdlib=libc++; 我在C++操作系统下工作,最近我提出了使用C++ 11的功能,这些功能是通过使用LIbC++STDLIB的CLAN+++编译器提供的。 但是,我还需要使用一些针对libstdc++编译和链接的遗留库(来自MacPorts),c++,c++11,clang,libstdc++,libc++,C++,C++11,Clang,Libstdc++,Libc++,在这样做的过程中,我得到了链接错误,因为传统库的头(例如,std::string)需要根据std::u 1::basic_string(即std::string的libc++实现)而不是std::basic_string实现进行解析 是否有一种方法可以在开发中混合使用这两个库(例如,通过使用一些预处理器标志?您看到的是使用内联名称空间来实现ABI版本控制 这意味着什么: libstdc++std::string是与libc++std::string不同的数据结构。前者是参考计数设计,而后者则不是

在这样做的过程中,我得到了链接错误,因为传统库的头(例如,
std::string
)需要根据
std::u 1::basic_string
(即
std::string
的libc++实现)而不是
std::basic_string
实现进行解析


是否有一种方法可以在开发中混合使用这两个库(例如,通过使用一些预处理器标志?

您看到的是使用内联名称空间来实现ABI版本控制

这意味着什么:

libstdc++
std::string
是与libc++
std::string
不同的数据结构。前者是参考计数设计,而后者则不是。尽管它们与API兼容,但与ABI不兼容。这意味着,如果您使用libstdc++构造一个
std::string
,然后将其传递给与libc++链接的其他代码,则接收代码会认为它有一个libc++
std::string
。也就是说,接收器不知道它应该增加或减少参考计数

如果没有内联名称空间,结果将是运行时错误。你最希望的就是撞车。对于内联命名空间,此运行时错误将转换为链接时错误

对于程序员来说,libstdc++
std::string
和libc++
std::string
看起来是相同的类型。但是对于链接器来说,它们看起来完全不同(线索是
std::\uu 1
名称空间)。链接器的观点是正确的。它们是完全不同的类型

所以,是的,你可以操纵一些预处理器标志来链接东西。但是,这样一来,您就需要花大量时间调试生成的运行时bug


要做到这一点,唯一的方法是使这些dylib之间的接口不涉及
std::
类型,例如
string
。例如,您可以传递字符数组。您甚至可以将内存所有权从libstdc++链接的代码转移到libc++链接的代码,反之亦然(它们都将进入同一个malloc池)。

因此,总结一下,在libc++中使用遗留库(即与libstdc++链接的库)是没有希望的。这确实是一个严重的限制。最大的希望是:只要不跨越动态库边界传递版本符号,就可以在一个过程中混合使用这两个库。如果您不小心这样做,错误会在链接时被捕获。您可以跨动态库边界抛出
std::exception
-派生的异常,并跨动态库边界转移内存所有权。我怀疑这可能比gcc自己的4.2版本提供的ABI兼容性更好。注意,根据std规范,在C++98/03和C++11之间,甚至连
std::string
都不兼容ABI。前者被广泛引用,而后者被禁止。另一个例子:C++11之前的gcc
std::list
与C++11规范的
std::list
不兼容。换句话说:您关于libc++的评论同样适用于libstdc++的C++11之前的版本(如果不是更多的话)。libc++与C++11之前版本的libstdc++的ABI兼容性并不比符合C++11标准的libstdc++更高。@user1690715更准确的说法是,当它们在API上公开STL对象时,不可能根据两个运行时构建互操作库,这一直是一个非常危险的命题。不是吗是否可以为std::string到std::1::string创建赋值重载,反之亦然?