C ++ Динамическая библиотека Компиляция / связывание - PullRequest
2 голосов
/ 22 апреля 2011

Я знаю, что если я свяжу свою программу на С ++ с динамической библиотекой (DLL), которая была построена с другой версией Visual Studio, она не будет работать из-за проблемы двоичной совместимости. (Я испытал это с библиотекой Boost и VS 2005 и 2008)

Но мой вопрос: так ли это для всех версий MSVS? Это относится и к статическим библиотекам (LIB)? Это проблема с GCC и Linux? и, наконец, как насчет связи в VS с DLL, созданной с помощью MinGW?

Кстати, кроме кроссплатформенности или кросс-компилятора, почему две версии одного и того же компилятора (VS) не могут быть совместимыми?

Ответы [ 3 ]

2 голосов
/ 22 апреля 2011

Привет. Я знаю, что если я свяжу свою программу на С ++ с динамической библиотекой (DLL), созданной с использованием другой версии Visual Studio, она не будет работать из-за проблемы двоичной совместимости. (Я испытал это с библиотекой Boost и VS 2005 и 2008)

Я не помню, чтобы когда-нибудь MS изменяла ABI, поэтому технически разные версии компилятора будут выдавать один и тот же результат (при одинаковых флажках (см. Ниже)).

Поэтому я не думаю, что это не несовместимость в Dev Studio, а изменения в Boost.
Различные версии boost не имеют обратной совместимости (в двоичном коде, source они обратно совместимы).

Но мой вопрос: так ли это для всех версий MSVS?

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

Это относится и к статическим библиотекам (LIB)?

Вы должны ссылаться на правильную статическую библиотеку. Но как только статическая библиотека находится в вашем коде, она застряла там, все разрешенные имена не будут повторно разрешены позднее.

Это также проблема с GCC и Linux?

Да. GCC несколько раз нарушал совместимость в ABI (несколько специально (некоторые по ошибке)). Это не настоящая проблема, поскольку в Linux код обычно распространяется как исходный код, и вы компилируете его на своей платформе, и он будет работать.

и, наконец, как насчет связи в VS с DLL, созданной с помощью MinGW?

Извините, я не знаю.

Кстати, кроме кроссплатформенности или кросс-компилятора, почему две версии одного и того же компилятора (VS) не могут быть совместимыми?

Хорошо полностью оптимизированные объекты кода могут быть сжаты больше, поэтому выравнивание отличается. Другие флаги компилятора могут влиять на способ генерирования кода, который несовместим с другими двоичными объектами (изменение способа вызова функций (все параметры в стеке или некоторые параметры в регистрах)). Технически только объекты, скомпилированные с одинаковыми флагами, должны быть связаны друг с другом (с технической точки зрения, это немного слабее, поскольку многие флаги не влияют на двоичную совместимость).

Обратите внимание, что некоторые библиотеки выпускаются с несколькими версиями одной и той же библиотеки, которые компилируются по-разному. Вы обычно отличаете библиотеку по расширению на конце. На моей последней работе мы использовали следующее соглашение.

libASR.dll   // A Sincgle threaded Relase  version lib
libASD.dll   // A Single  threaded Debug   version
libAMR.dll   // A Multi   threaded Release version
libAMD.dll   // A Multi   threaded Debug   version
0 голосов
/ 22 апреля 2011

Чтобы ответить на часть вашего вопроса, GCC / Linux не имеет этой проблемы. По крайней мере, не так часто. libstdc ++ и glibc - это стандартные библиотеки C ++ / C в системах GNU, и авторы этих библиотек прилагают усилия, чтобы избежать нарушения совместимости. glibc почти всегда обратно совместим, но libstdc ++ несколько раз нарушал ABI в прошлом и, вероятно, будет снова в будущем.

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

На практике это не так уж важно для Windows. Было бы замечательно, если бы Microsoft просто дала установщику MSI знать, как извлекать предоставляемые Microsoft DLL из Центра обновления Windows, когда установлено приложение, которое нуждается в них, но достаточно просто добавить распространяемый файл в сгенерированный InnoSetup установщик.

0 голосов
/ 22 апреля 2011

При правильной сборке библиотеки DLL должны быть независимыми от языка программирования и версии. Вы можете ссылаться на библиотеки DLL, созданные с использованием VB, C, C ++ и т. Д.

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

...