Использовать C++ DLL из одной и той же VS, скомпилированной в разное время / команды - совместимость ABI?
Повторюсь: я ищу совместимость ABI между библиотеками одной и той же версии Visual-C++!
Мы хотим смешивать и сопоставлять некоторые внутренние библиотеки C++ DLL из разных команд - созданные в разное время с разными файлами проекта. Из-за длительного времени сборки мы точно хотим избежать больших монолитных сборок, когда каждая команда перекомпилирует исходный код библиотеки другой команды.
При использовании библиотек DLL C++ с интерфейсами C++ совершенно очевидно, что вы можете сделать это, только если все библиотеки DLL скомпилированы с одинаковой версией компилятора / Visual Studio.
Что мне не совсемпонятно, так это то,что должно быть точно так же, чтобы получить совместимость с ABI.
- Очевидно, отладка (
_DEBUG
) и выпустить (NDEBUG
) нельзя смешивать - но это также очевидно из того факта, что они ссылаются на разные версии общего времени выполнения. - Нужна ли вам точно такая же версия компилятора, или достаточно, чтобы результирующая DLL ссылалась на одну и ту же общую среду выполнения C++ - то есть, в основном, на один и тот же распространяемый? (Я думаю, что static не вылетает при передаче полных объектов C++ вокруг)
- Есть ли документированный список опций компилятора(и компоновщика), которые должны быть одинаковыми для совместимости двух DLL C++ одной и той же версии vC++?
- Например, это то же самое
/O
необходимо переключение - влияет ли уровень оптимизации на совместимость ABI? (Я уверен, что нет.) - Или обе версии должны использовать один и тот же
/EH
переключатель? - Или же
/volatile:ms|iso
...?
- Например, это то же самое
По сути, я хотел бы предложить набор (мета) данных для связи с Visual-C++ DLL, который описывает его совместимость с ABI.
Если есть различия, я сосредоточен на VS2015 только на данный момент.
1 ответ
Я думал об этом последние дни, и я попытался выяснить, существуют ли какие-то варианты использования, где разработчикам уже нужно было классифицировать их сборку C++, чтобы убедиться, что двоичные файлы совместимы.
Одним из таких мест являются Native Packages от nuget. Поэтому я посмотрел на один пакет, в частности, на cpprestsdk:
Двоичные файлы в загружаемом пакете разделены следующим образом:
native\v120\windesktop\msvcstl\dyn\rt-dyn\x64\Release\
^ ^ ^ ^ ^
VS version | not sure | uses cpp-runtime dynamically
| lib itself dynamic (as opposed to static)
or WinXP or WinApp(WinRT?)
Я извлек это из этого примера, потому что я не мог найти другие документы. Я также знаю, что каталог сборки бинарных файлов Boost разделен аналогичным образом.
Итак, чтобы получить список метаданных для определения совместимости ABI, я могу предварительно перечислить следующее:
- Версия VC (то есть версия используемых библиотек времени выполнения C и CPP)
- один момент здесь в том, что, например,
vc140
в настоящее время должно быть достаточно - учитывая, как CRT связан, все возможные исправления для версионных компонентов CRT должны быть в любом случае совместимы с ABI, поэтому не должно иметь значения, с какой версией была создана данная предварительно скомпилированная библиотека.
- один момент здесь в том, что, например,
- чистый родной | управляемый (/CLI) | WinRT
- как потребляется ЭЛТ (статически / динамически)
- битность / платформа (Win32, x64, ARM и т. д.)
- Релиз или отладочная версия (т.е. на какую версию CRT мы ссылаемся)
- плюс:
_ITERATOR_DEBUG_LEVEL
... если все идут с настройками по умолчанию, хорошо, если проект не делает, он должен объявить так
Кроме того, я предпочитаю следующие пункты:
/O
не должно иметь значения - мы постоянно смешиваем и сопоставляем двоичные файлы с различными настройками оптимизации - в частности, это работает даже для объектных файлов в одном двоичном файле/volatile
- так как это дело кодов, мне трудно представить, как это может сломать ABI/EH
- за исключением опции отключения всех исключений, в этом случае вы, очевидно, не можете вызывать ничего, что выдает, я вполне уверен, что это сохранение с точки зрения ABI: здесь возможны подводные камни, но я думаю, что они не могут на самом деле быть классифицированы в ABI Compat. (Может быть, можно сказать, что некоторые сложные цепочки обратных вызовов несовместимы с ABI, не уверен)
Другие:
- Соглашение о вызовах по умолчанию (
/G..
): Я думаю, что это сломалось бы во время ссылки, когда искаженные символы экспорта и объявления заголовков не совпадают. /Zc:wchar_t
- сломается во время соединения (на самом деле это совместимо с ABI, но символы не будут отображаться.)- Включить RTTI (
/GR
) - не слишком уверен насчет этого - я никогда не работал с этим отключенным.