我正在使用RHEL 5.3,它随gcc 4.1.2和1.33一起提供。 我想要的一些功能,在增强1.33中缺失。 因此,我们的想法是升级到1.43的新增助推出。
是否可以同时使用boost 1.43中的一些仅限标题的库,其余来自1.33?例如,我想使用unorded_map,它在boost 1.33中缺失。
是否可以使用来自不同版本的并发二进制增强库?
答案 0 :(得分:14)
不 - 永远不要这样做!
这是不可能的,你可能会意外崩溃。
正确完成它的唯一方法是使用命名空间重命名:即创建替代方法 将版本放在不同的名称空间中。
最新版本的BCP提供此选项。因此,您将使用boost_1_43而不是boost。但对你来说这将是非常透明的。但你仍应该意识到 你不能在同一个cpp文件中使用两个版本的boost。
另请参阅此讨论:Creating Library with backward compatible ABI that uses Boost
喜欢的脚本重命名命名空间,定义和包含,因此您实际上可以包含两个 像
这样的提升版本#include <boost/foo.hpp>
#include <myboost/bar.hpp>
boost::foo f;
myboost::bar b;
Boost BCP不允许这样做。
但是你应该小心,因为有些库没有输出extern“C”符号 boost前缀,boost :: thread和boost :: regex的C API(regexec,regcomp)
修改强>
作为此类问题的示例,请创建以下文件:
a.cpp:
template<typename Foo>
Foo add(Foo a, Foo b)
{
return a+b;
}
int foo(int x,int y)
{
return add(x,y);
}
b.cpp:
template<typename Foo>
Foo add(Foo a, Foo b)
{
return a-b;
}
int bar(int x,int y)
{
return add(x,y);
}
TEST.CPP:
#include <iostream>
int foo(int,int);
int bar(int,int);
int main()
{
std::cout<< foo(10,20) <<" " <<bar(10,20) << std::endl;
}
编译它们:
g++ a.cpp b.cpp test.cpp
你会期望:
30 -10
但你会得到
30 30
或
-10 -10
取决于链接顺序。
因此,使用两个boost版本时,您可能会意外地使用其他boost和crash中的符号
与此程序中的符号int add<int>(int,int)
相同,甚至可以解析为相同的符号
如果它放在不同的编译单元中。
答案 1 :(得分:3)
有了一点运气(并且非常小心),你可以可能使用全新的标题。对于其他任何事情,它可能会匆忙变得丑陋,因为Boost的某些部分引用其他部分,如果某些v.1.33代码意外地为其依赖性加载v.1.43头部,那么你很有可能会去结果会出现一些问题 - 你可以期待的最好的是那时快速,干净的死亡(崩溃),但你可能会变得更加糟糕(例如,无声的数据损坏)。
答案 2 :(得分:1)
<强>更新强>
我认为我的原始答案对链接器的功能和使用的选项做了太多假设,这可能是完全错误的。通常我会删除它,但是在讨论中有一些要点没有包含在其他答案中。
我发现构建一个表现良好的闭源库所需要的含义令人惊讶。
原始答案
只要您在每个编译步骤中使用一个版本,那么您应该没问题,因为代码是在编译时生成的,生成的符号应该限制在编译步骤的范围内。
我假设Boost仍然是一个没有可链接库的模板库。如果不是,那么只要你没有链接到多个版本的库,你仍然可以。
我可能在这方面错了,但暗示是你不能使用针对不同版本的Boost构建的任何第三方库,而不是为你的应用程序定义的版本。我没有阅读或听到的任何内容甚至暗示这种限制适用。
如果您正在构建自己的应用程序,那么我会坚持使用一个版本的Boost来处理您自己的所有代码。它不必与RHEL提供的版本相同。
<强>更新强>
与Artyom的例子相比,我所谈论的场景更像是这样:
g++ -c -I/usr/include/boost_1.31 a.cpp
g++ -c -I/usr/include/boost_1.39 b.cpp
ar rcs liba.a a.o
ar rcs libb.a b.o
g++ -I/usr/include/boost_1.41 test.cpp liba.a libb.a -o test
...现在我理解Artyom的观点,因为它取决于链接器是否更喜欢同一个库文件中的符号。