Кросс-компилятор Бинарная совместимость в C

Мне нужно проверить что-то, за что у меня есть сомнения. Если общая библиотека (.dll) написана на C, со стандартом C99 и скомпилирована под компилятором. Скажите MinGw. Тогда, по моему опыту, он совместим с бинарными и, следовательно, можно использовать из любого другого компилятора. Скажите MS Visual Studio. Я говорю по своему опыту, потому что я пробовал это успешно более одного раза. Но мне нужно проверить, является ли это правилом.

И кроме того, я хотел бы спросить, действительно ли это так, то почему библиотеки, написанные полностью на C, например openCV, не предоставляют скомпилированные двоичные файлы для каждой другой ОС? Я знаю, что очевидной причиной было бы установить все параметры времени компиляции, но кроме того, что нет прав?

EDIT: Я добавляю дополнительный вопрос, который я рассматриваю как логическое расширение оригинала. Разве это не так, как можно было бы создать закрытую исходную библиотеку? Так как опция подачи источника выходит из окна, предоставление двоичных файлов является единственным выбором. И в этом случае предоставление двоичных файлов для как можно большего количества архитектур является желаемым результатом, причем C является очевидным выбором для обеспечения лучшей переносимости между системами и компиляторами. Правильно?

Ответ 1

В конкретном случае компиляторов C (MSVC и GCC/MinGW) в мире Windows вы правы в предположении совместимости с двоичными файлами. Можно связать DLL-интерфейс C, скомпилированный GCC, в программу в Visual Studio. Это то, как проекты C99, такие как ffmpeg, позволяют разработчикам писать приложение с Visual Studio. Нужно только создать библиотеку импорта с lib.exe, найденную в инструментальной цепочке Microsoft из DLL. Или наоборот, используя mingw.org pexports или лучше, mingw-w64 gendef tool, можно создать библиотеку импорта GCC для созданной MSVC DLL.

Эта удобная функциональная совместимость ломается, когда вы входите в мир интерфейса С++, где ABI MSVC и GCC отличаются и несовместимы. Это может сработать, возможно, нет, никаких гарантий и никаких усилий (в настоящее время) не делается при их изменении. Кроме того, информация об отладке, очевидно, различна, пока кто-то не пишет генератор/запись информации отладки в GCC, который совместим с отладчиком MSVC (наряду с поддержкой gdb, конечно).

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

Обратите внимание, что, как сказал Vijay, по-прежнему существует разница в архитектуре, поэтому при подключении к библиотеке AMD64 нельзя использовать библиотеку x86.


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

Именно так вы создадите двоичный файл с закрытым исходным кодом. В дополнение к библиотеке импорта очень важно скрыть экспорт из DLL, что делает DLL самой бесполезной для связывания (если вы не хотите, чтобы клиентский код использовал частные функции в библиотеке, см., Например, вывод dumpbin /exports в MSOffice DLL, там много скрытого материала). Вы можете добиться того же самого с GCC (я верю, никогда не использовал или не пробовал) с помощью таких вещей, как __attribute(hidden) и т.д.

Некоторые специфические для компилятора точки:

  • MSVC поставляется с четырьмя (ну, на самом деле только тремя оставшимися в более новых версиях) различными библиотеками времени выполнения через /MT,/MD и/LD. Кроме того, вам необходимо предоставить сборку для каждой версии Visual Studio (включая пакеты обновлений), чтобы обеспечить совместимость. Но это закрытый двоичный код и Windows для вас...

  • GCC не имеет этой проблемы; MinGW всегда ссылается на msvcrt.dll, предоставляемый Windows (начиная с Windows 98), эквивалентно /MD (и, возможно, также эквивалентной библиотеке отладки с /MDd ). Но у меня есть две версии MinGW (mingw.org и mingw-w64), которые не гарантируют совместимость с двоичными файлами. Последний является более полным, поскольку он предоставляет 64-битные опции, а также 32-битные, и предоставляет более полный набор заголовков/библиотек (включая значительную часть DirectX и DDK).

Ответ 2

Общее правило заключается в том, что если ваша комбинация ОС/ЦП имеет стандартный ABI и ЕСЛИ, что ABI достаточно мощна для вашего языка, большинство компиляторов будут следовать этому ABI и, как результат, будут бинарно совместимыми, что позволит вам связывать библиотеки (общий или статический), скомпилированный с различными компиляторами, в программы, скомпилированные с другими компиляторами, просто отлично.

Проблема в том, что большинство ABI довольно слабы - они разработаны на языках низкого уровня, таких как C и FORTRAN, и датируются временем до объектно-ориентированных языков, таких как С++. Таким образом, они, как правило, не поддерживают такие функции, как перегрузка функций, пользовательские операторы, исключения, глобальные конструкторы и деструкторы, виртуальные функции, наследование и т.д., Которые необходимы С++.

Этот недостаток был распознан, когда был разработан С++, поэтому С++ имеет extern "C" - что заставляет компилятор ограничиваться стандартным ABI для определенных функций, отключая все дополнительные функции С++, которые ABI обычно не используют поддержка.

Ответ 3

Общая библиотека или dll, скомпилированные для конкретной архитектуры, могут быть связаны с приложениями, скомпилированными другими компиляторами, которые нацелены на одну и ту же архитектуру. (По архитектуре я имею в виду комбинацию процессор/ОС). Но разработчик библиотеки не имеет возможности компилировать все возможные архитектуры. Более того, когда библиотека распределяется в исходной форме, пользователи могут создавать бинарные файлы, оптимизированные с учетом их конкретных требований.