Кросс-компилятор двоичной совместимости в C - PullRequest
10 голосов
/ 25 июля 2011

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

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

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

Ответы [ 3 ]

6 голосов
/ 25 июля 2011

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

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

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

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


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

Именно так вы и создадите двоичный файл с закрытым исходным кодом. В дополнение к библиотеке импорта также очень важно скрыть экспорт из DLL, что делает саму DLL бесполезной для компоновки (если вы не хотите, чтобы клиентский код использовал частные функции в библиотеке, см., Например, вывод dumpbin /exports в MSOffice DLL, там много скрытых вещей). Вы можете достичь того же самого с 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).

4 голосов
/ 25 июля 2011

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

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

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

2 голосов
/ 25 июля 2011

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

...