代码之家  ›  专栏  ›  技术社区  ›  dimba

同时使用两个版本的Boost

  •  12
  • dimba  · 技术社区  · 15 年前

    我使用的是RHEL5.3,它与GCC4.1.2和Boost1.33一起提供。 Boost1.33中缺少一些我想要的功能。 因此,我们的想法是升级到Fresh Boost 1.43版。

    1. 是否可以同时使用Boost 1.43和1.33中的一些仅头部库?例如,我想使用Boost1.33中缺少的无序图。

    2. 是否可以同时使用来自不同版本的二进制增强库?

    3 回复  |  直到 15 年前
        1
  •  14
  •   Community CDub    8 年前

    不--永远不要这样做!

    这是不可能的,你很可能会意外撞车。

    正确完成此操作的唯一方法是使用命名空间重命名:即创建替代项 Boost版本已放入 不同的 命名空间。

    BCP的最新版本提供了此选项。所以你将使用像Boost_1_43这样的东西而不是Boost。但这对你来说是相当透明的。但你还是应该知道 在同一个cpp文件中不能使用两个版本的boost。

    另请看下面的讨论: Creating Library with backward compatible ABI that uses Boost

    喜欢的脚本重命名名称空间,定义和包含,这样实际上可以包括两个 Boost-Like的版本

    #include <boost/foo.hpp>
    #include <myboost/bar.hpp>
    
    boost::foo f;
    myboost::bar b;
    

    Boost BCP不允许这样做。

    但是您仍然应该小心,因为有些库导出外部“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);
    }
    

    测试: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) 甚至被解析为相同符号 如果它放在不同的编译单元中。

        2
  •  3
  •   Jerry Coffin    15 年前

    如果你运气好(而且非常小心),你可以 可能 避免使用全新的邮件头。对于几乎所有其他的事情,它可能会在匆忙中变得丑陋,因为Boost的某些部分涉及到其他部分,并且如果一些v.1.33代码意外地加载了v.1.43头部作为其依赖项,那么很有可能您会因此遇到一些问题——您所能希望的最好的方法是在此时快速、干净地死亡(崩溃),但是y您可能很容易变得更糟(例如,无声数据损坏)。

        3
  •  1
  •   richj    15 年前

    更新

    我认为我最初的答案对链接器的功能和所使用的选项做了太多的假设,这很可能是完全错误的。通常我会删除它,但在讨论中有一些要点没有包含在其他答案中。

    我发现构建一个行为良好的闭源代码库所需要的东西所带来的影响是惊人的。

    原始答案

    只要在每个编译步骤中使用一个版本,那么就应该是正常的,因为代码是在编译时生成的,生成的符号应该限制在编译步骤的范围内。

    我假设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的观点,因为这取决于链接器是否喜欢同一个库文件中的符号。