Контейнеры STL и двоичный интерфейс - PullRequest
2 голосов
/ 06 декабря 2011

STL двоичные интерфейсы

Мне любопытно узнать, работает ли кто-нибудь над совместимыми интерфейсными слоями для объектов STL на нескольких компиляторах и платформах для C ++.

Целью будет поддержка типов STL как первоклассных или внутренних типов данных.

Есть ли какое-то внутреннее ограничение дизайна, накладываемое шаблонами в целом, которое предотвращает это? Это кажется основным ограничением использования STL для двоичного распределения.

Теория - Возможно, ответ прагматичен

  1. Microsoft приложила усилия к .NET и на самом деле не заботится о том, чтобы поддержка C ++ STL была "первым классом".

  2. Открытый исходный код не хочет продвигать дистрибутив только для двоичного кода и фокусируется на правильном подходе с помощью одного компилятора вместо несоответствия 10 различных версий.

Кажется, это подтверждается моим опытом работы с Qt и другими библиотеками - они обычно предоставляют сборку для среды, которую вы собираетесь использовать. Qt 4.6 и VS2008, например.

Ссылки:

Ответы [ 3 ]

3 голосов
/ 06 декабря 2011

Я думаю, что проблема предшествует вашей теории: C ++ не определяет ABI (двоичный интерфейс приложения).

На самом деле даже C не делает этого, но, будучи библиотекой C просто набором функций (и может быть глобальными переменными), ABI - это просто название самих функций. В зависимости от платформы имена можно каким-то образом искажать, но, поскольку каждый компилятор должен иметь возможность выполнять системную калибровку, все заканчивается тем же соглашением компоновщика операционной системы (в Windows _cdecl просто приводит к добавлению _ к названию функции.

Но в C ++ есть перегрузка, поэтому требуется более сложная схема искажения. На сегодняшний день не существует соглашения между производителями компиляторов о том, как такое искажение должно быть сделано. Технически невозможно скомпилировать статическую библиотеку C ++ и связать ее с OBJ C ++, полученным из другого компилятора. То же самое относится и к DLL.

И поскольку все компиляторы различны даже для скомпилированных перегруженных функций-членов, на самом деле никто не решает проблему шаблонов.

Технически это МОЖЕТ быть предоставлено путем введения перенаправления для каждого параметрического типа и введения таблиц диспетчеризации, но ... это делает шаблонную функцию не отличающейся (с точки зрения диспетчеризации вызовов) от виртуальных функций виртуальных баз, таким образом делая производительность шаблона стать похожим на классическую ООП диспетчеризацию (хотя это может ограничить вздутие кода ... компромисс не всегда очевиден)

В настоящее время, похоже, что производители компиляторов не заинтересованы в согласии с общим стандартом, поскольку он пожертвует всеми различиями в производительности, которые может иметь каждый производитель, с его собственной оптимизацией.

2 голосов
/ 06 декабря 2011

Мне любопытно узнать, работает ли кто-нибудь над совместимыми интерфейсными слоями для объектов STL на нескольких компиляторах и платформах для C ++.

Да, я согласен.Я работаю над уровнем стандартизированных интерфейсов, который вы можете (помимо прочего) использовать для передачи двоичных безопасных «управляемых» ссылок на экземпляры типов STL, Boost или других типов C ++ через границы компонентов.Библиотека (называемая 'Vex') предоставит реализации этих интерфейсов, а также соответствующие фабрики для упаковки и развертывания популярных std :: или boost :: types.Кроме того, библиотека предоставляет LINQ-подобные операторы запросов для фильтрации и манипулирования содержимым того, что я называю Range и RangeSource.Библиотека еще не готова к публикации, но я собираюсь опубликовать более раннюю версию предварительного просмотра как можно скорее ...

Пример:

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 являетсяне изобретать колесо - оно только добавляет этот интерфейсный слой плюс некоторую необходимую инфраструктуру и синтаксический сахар для запросов.

Cheers,

Paul

2 голосов
/ 06 декабря 2011

Шаблоны C ++ - это код, сгенерированный во время компиляции.
Это означает, что если вы хотите использовать шаблонный класс, вы должны включить его заголовок (объявление), чтобы компилятор мог сгенерировать правильный код для шаблонного класса, который вам нужен.

Таким образом, шаблоны не могут быть предварительно скомпилированы в двоичные файлы.

То, что дают вам другие библиотеки, это предварительно скомпилированные классы базовых утилит, которые не являются шаблонными.

Например, C # дженерики скомпилированы в код IL в виде dll или исполняемых файлов.
Но IL-код подобен другому языку программирования, так что это позволяет компилятору читать обобщенную информацию из включенной библиотеки.

.Net IL-код компилируется в настоящий двоичный код во время выполнения, поэтому компилятор во время выполнения имеет всеопределения, необходимые в IL для генерации правильного кода для обобщений.

...