В настоящее время я разрабатываю библиотеку С++ для Windows, которая будет распространяться как DLL. Моя цель - максимизировать двоичную совместимость; более точно, функции в моей DLL должны использоваться из кода, скомпилированного с несколькими версиями MSVС++ и MinGW, без необходимости перекомпилировать DLL. Тем не менее, я смущен тем, какая конвенция лучше всего подходит, cdecl
или stdcall
.
Иногда я слышу такие утверждения, как "соглашение о вызове C - это единственное, гарантированное быть одним и тем же компрометирующим", что контрастирует с такими выражениями, как "Есть некоторые вариации в интерпретации cdecl
, особенно в том, как возвращать значения ". Это, похоже, не останавливает некоторых разработчиков библиотек (например, libsndfile), чтобы использовать соглашение C-вызова в DLL, которые они распространяют, без видимых проблемы.
С другой стороны, соглашение о вызове stdcall
кажется хорошо определенным. Из того, что мне сказали, все компиляторы Windows в основном обязаны следовать за ним, поскольку это соглашение используется для Win32 и COM. Это основано на предположении, что компилятор Windows без поддержки Win32/COM не будет очень полезен. Множество фрагментов кода, размещенных на форумах, объявляет функции как stdcall
, но я не могу найти одно сообщение, которое четко объясняет, почему.
Там слишком много противоречивой информации, и каждый поиск, который я запускаю, дает мне разные ответы, которые на самом деле не помогают мне решить между ними. Я ищу четкое, подробное, аргументированное объяснение, почему я должен выбирать один над другим (или почему они эквивалентны).
Обратите внимание, что этот вопрос относится не только к "классическим" функциям, но также к вызовам функций виртуальных членов, поскольку большинство клиентских кодов будут взаимодействовать с моей DLL через "интерфейсы", чистые виртуальные классы (следующие шаблоны, например, здесь и там).