2

STL 二进制接口

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

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

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

理论——也许答案是务实的

  1. 微软已经在 .NET 上投入了精力,并不真正关心 C++ STL 支持是“一流的”。

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

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

参考:

4

3 回答 3

3

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

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

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

而且由于编译器即使对于已编译的重载成员函数也是不同的,因此实际上没有人承担模板的问题。

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

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

于 2011-12-06T08:19:04.037 回答
2

C++ 模板是编译时生成的代码。
这意味着如果你想使用一个模板类,你必须包含它的头文件(声明),这样编译器才能为你需要的模板类生成正确的代码。

因此,模板不能预编译为二进制文件。

其他库为您提供的是未模板化的预编译基本实用程序类。

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

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

于 2011-12-06T05:37:40.597 回答
2

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

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

例子:

com1std::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 的 Ranges...“Vex”的基本意图之一不是重新发明轮子——它只是添加了接口层以及一些必需的基础设施和句法查询的糖。

干杯,

保罗

于 2011-12-06T08:41:44.240 回答