Вопрос

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

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

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

Это было полезно?

Решение

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

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

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

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


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

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

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

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

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

Другие советы

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top