使用libstdc ++编译库与clang ++ -stdlib = libc ++ [英] Using libstdc++ compiled libraries with clang++ -stdlib=libc++

查看:875
本文介绍了使用libstdc ++编译库与clang ++ -stdlib = libc ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Mac OS X(10.8.2)中使用C ++,我最近想出了使用C ++ 11功能的需要,这些功能可以通过clang ++编译器使用libc ++ stdlib。
然而,我还需要使用一些遗留的库编译和链接到libstdc ++(来自MacPorts)。



这样做时,我发现链接错误,因为使用例如 std :: string ,需要根据 std :: __ 1 :: basic_string (即libc ++实现 std :: string )而不是 std :: basic_string 实现。



有一种方法来混合这两个库在开发中(例如使用一些预处理器标志?)

解决方案

您看到的是使用<


$ b

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



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



给程序员libstdc ++ std :: string 和libc ++ std :: string 看起来像相同的类型。但对于链接器,它们看起来像完全不同的类型(线索是 std :: __ 1 命名空间)。链接器的视图是正确的。 是完全不同的类型。



是的,你可以操纵一些预处理器标志来链接。但是,你会有一个时间调试的结果运行时bug的恶魔。



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


I am working in C++ under Mac OS X (10.8.2) and I recently came up with the need of using C++11 features, which are available through the clang++ compiler using the libc++ stdlib. However, I also need to use some legacy library compiled and linked against libstdc++ (coming from MacPorts).

In doing so, I got linking errors, since the headers of the legacy libraries using, e.g., std::string, required to be resolved against the std::__1::basic_string (i.e., the libc++ implementation of std::string) instead of the std::basic_string implementation.

Is there a way to mix the two libraries in development (e.g. by using some preprocessors flags?)

解决方案

What you're seeing is the use of inline namespaces to achieve ABI versioning.

What that means:

The libstdc++ std::string is a different data structure than the libc++ std::string. The former is a reference counted design, whereas the latter is not. Although they are API compatible, they are not ABI compatible. That means that if you construct a std::string with libstdc++, and then pass it to other code that is linked against libc++, the receiving code would think it has a libc++ std::string. I.e. the receiver would not have a clue that it should be incrementing or decrementing reference counts.

Without inline namespaces, the result would be a run time error. The best you could hope for is a crash. With inline namespaces this run time error is translated into a link time error.

To you the programmer the libstdc++ std::string and the libc++ std::string look like the same type. But to the linker, they look like completely different types (the clue is the std::__1 namespace). And the linker's view is correct. They are completely different types.

So yes, you could manipulate some preprocessor flags to get things to link. But then you would have a devil of a time debugging the resultant run time bugs.

The only way to do what you want to is to make the interfaces between these dylibs not involve std:: types such as string. For example you could pass arrays of char instead. You can even transfer memory ownership from libstdc++-linked code to libc++-linked code and vice-versa (they will both drop through to the same malloc pool).

这篇关于使用libstdc ++编译库与clang ++ -stdlib = libc ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆