STL容器和二进制接口兼容性

时间:2011-12-06 05:27:44

标签: c++ stl interface binary-compatibility abi

STL二进制接口

我很想知道是否有人在C ++的多个编译器和平台上为STL对象开发兼容的接口层。

目标是支持STL类型作为一流或内在数据类型。

一般来说,模板是否存在一些固有的设计限制可以防止这种情况?这似乎是使用STL进行二进制分发的一个主要限制。

理论 - 也许答案是务实的

  1. 微软已经付出了努力,并没有真正关心C ++ STL支持是“一流的”。

  2. 开源不希望推广仅二进制分发,而是专注于使用单个编译器来解决问题,而不是10个不同版本的不匹配。

  3. 这似乎得到了我对Qt和其他库的经验的支持 - 它们通常为您将要使用的环境提供构建。例如,Qt 4.6和VS2008。

    参考文献:

3 个答案:

答案 0 :(得分:3)

我认为问题优先于你的理论:C ++没有指定ABI(应用程序二进制接口)。

实际上即使C没有,但作为C库只是函数的集合(可能是全局变量),ABI只是函数本身的名称。根据平台的不同,名称可能会以某种方式被破坏,但是,由于每个编译器都必须能够放置系统calss,所以一切都使用操作系统构建器的相同约定(在Windows中,_cdecl只会导致前置_到函数名。

但是C ++有重载,因此需要更复杂的修改方案。 到目前为止,编译器制造商之间尚未达成关于如何进行此类修改的协议。 从技术上讲,编译C ++静态库并将其链接到来自另一个编译器的C ++ OBJ是不可能的。 DLL也是如此。

由于编译器在编译的重载成员函数中都是不同的,因此没有人真正提供模板问题。

从技术上讲,它可以通过为每个参数类型引入重定向,并引入调度表但是......这使得模板化函数(在调用调度方面)与虚拟基础的虚函数没有区别,从而使模板性能变得类似于经典的OOP调度(虽然它可以限制代码膨胀......权衡并不总是显而易见的)

目前,似乎编译器制造商之间没有兴趣同意通用标准,因为它会牺牲每个制造商可能拥有的所有性能差异。

答案 1 :(得分:2)

C ++模板是编译时生成的代码 这意味着如果要使用模板化类,则必须包含其标头(声明),以便编译器可以为您需要的模板化类生成正确的代码。

因此,模板无法预编译为二进制文件。

其他库提供的是预编译的非模板化的基础实用程序类。

例如,C#泛型以dll或可执行文件的形式编译成IL代码 但IL代码就像另一种编程语言,所以这允许编译器从包含的库中读取泛型信息。

.Net IL代码在运行时被编译成实际的二进制代码,因此运行时的编译器具有IL中需要的所有定义,以便为泛型生成正确的代码。

答案 2 :(得分:2)

  

我很想知道是否有人正在使用兼容的界面   跨多个编译器和平台的STL对象的层   C ++。

是的,我是。我正在开发一层标准化接口,您可以(除其他外)使用它来跨组件边界将二进制安全“托管”引用传递给STL,Boost或其他C ++类型的实例。该库(称为'Vex')将提供这些接口的实现以及适当的工厂来包装和解包流行的std ::或boost ::类型。此外,该库提供类似LINQ的查询运算符,用于过滤和操作我称之为RangeRangeSource的内容。图书馆还没有准备好“上市”,但我打算尽快发布一个早期的“预览版”...

示例:

com1将对std::vector<uint32_t>的引用传递给com2

com1:

class Com2 : public ICom1 {
    std::vector<int> mVector;

    virtual void Com2::SendDataTo(ICom1* pI)
    {
        pI->ReceiveData(Vex::Query::From(mVector) | Vex::Query::ToInterface());
    }
};

com2:

class Com2 : public ICom2 {
    virtual void Com2::ReceiveData(Vex::Ranges::IRandomAccessRange<uint32_t>* pItf)
    {
        std::deque<uint32_t> tTmp;
        // filter even numbers, reverse order and process data with STL or Boost algorithms
        Vex::Query::From(pItf)
            | Vex::Query::Where([](uint32_t _) -> { return _ % 2 == 0; })
            | Vex::Query::Reverse
            | Vex::ToStlSequence(std::back_inserter(tTmp));
        // use tTmp...
    }
};

你会认识到与各种熟悉概念的关系:LINQ,Boost.Range,any_iterator和D's Ranges ......'Vex'的基本意图之一不是重新发明轮子 - 它只是添加了界面层加上一些必需的用于查询的基础结构和语法糖。

干杯,