Компилятор 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 и общему компилятору.
но...
помните:
- GCC / c++ сохраняет свой ABI стабильным с выпуска 3.4, и это около 7 лет (с 2004 года), в то время как MSVC ломает свой ABI каждый основной выпуск: MSVC8 (2005), MSVC9 (2008), MSVC10 (2010) несовместимы друг с другом.
- некоторые часто используемые флаги с MSVC также могут нарушать ABI (например, модель исключений)
- MSVC имеет несовместимое время выполнения для режимов отладки и выпуска.
Так что да, вы можете использовать эти правила, но, как и в обычном случае MSVC, у него гораздо больше причуд.
Смотрите также на "некоторые мысли о бинарной совместимости " и Qt держит их ABI стабильными с MSVC как что ж.
Примечание у меня есть некоторый опыт работы с этим, поскольку я следую этим правилам в CppCMS
в Windows у вас в основном есть 2 варианта долгосрочной бинарной совместимости:
- COM
- имитация COM
проверьте мой пост здесь. Там вы увидите способ создания DLL и доступа к 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 использует эту гибкость.