Компилятор GCC vs MS C++ для поддержания обратной двоичной совместимости API

Я пришел из мира Linux и знаю много статей о поддержании обратной двоичной совместимости (BC) API динамической библиотеки, написанной на языке C++. Один из них - " Политики / Проблемы Бинарной Совместимости С C++" на основе Itanium C++ ABI, который используется компилятором GCC. Но я не могу найти ничего подобного для компилятора Microsoft C++ (от MSVC).

Я понимаю, что большинство методов применимы к MS c++ компилятор и я хотели бы открыть специфичный для компилятора проблемы, связанные с различиями ABI (макет v-таблицы,искажение и т. д.)

Итак, мои вопросы следующие:

  • знаете ли вы какие-либо различия между компиляторами MS C++ и GCC при обслуживании BC?
  • где я могу найти информацию о MS C++ ABI или о поддержании BC API в Windows?

любая родственная информация будет сильно оцененный.
Большое спасибо за вашу помощь!

3 ответов


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

таким образом, в основном эти правила полностью применимы к MSVC и общему компилятору.

но...

помните:

  1. GCC / c++ сохраняет свой ABI стабильным с выпуска 3.4, и это около 7 лет (с 2004 года), в то время как MSVC ломает свой ABI каждый основной выпуск: MSVC8 (2005), MSVC9 (2008), MSVC10 (2010) несовместимы друг с другом.
  2. некоторые часто используемые флаги с MSVC также могут нарушать ABI (например, модель исключений)
  3. MSVC имеет несовместимое время выполнения для режимов отладки и выпуска.

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

Смотрите также на "некоторые мысли о бинарной совместимости " и Qt держит их ABI стабильными с MSVC как что ж.

Примечание у меня есть некоторый опыт работы с этим, поскольку я следую этим правилам в CppCMS


в Windows у вас в основном есть 2 варианта долгосрочной бинарной совместимости:

  1. COM
  2. имитация COM

проверьте мой пост здесь. Там вы увидите способ создания DLL и доступа к DLL двоичным совместимым способом в разных компиляторах и версиях компилятора.

C++ DLL плагин интерфейс


лучшим правилом для двоичной совместимости MSVC является использование интерфейса C. Единственная функция C++, с которой вы можете уйти, по моему опыту,-это интерфейсы с одним наследованием. Поэтому представляйте все как интерфейсы, которые используют типы данных C.

вот список вещей, которые не бинарная совместимость:

  • STL. Двоичный формат изменяется даже между отладкой/выпуском и в зависимости от флагов компилятора, поэтому вам лучше не использовать STL кросс-модуль.
  • кучи. Не new / malloc в одном модуле и delete / free в другой. Есть разные кучи, которые не знают друг о друге. Еще одна причина, по которой STL не будет работать с кросс-модулями.
  • исключения. Не позволяйте исключениям распространяться из одного модуля в другой.
  • RTTI / dynamic_casting типы данных из других модулей.
  • не доверяйте другим функциям C++.

короче говоря, C++ не имеет последовательный ABI, но C делает, поэтому избегайте пересечения модулей функций c++. Поскольку одиночное наследование является простой v-таблицей, вы можете использовать его для предоставления объектов C++, при условии, что они используют типы данных C и не делают перекрестных распределений кучи. Это подход, используемый самими Microsoft, а также, например, для Direct3D API. GCC может быть полезен в обеспечении стабильного ABI, но стандарт не требует этого, и MSVC использует эту гибкость.