Как правильно создать стороннюю библиотеку для использования в конфигурациях отладки и выпуска в моем проекте?

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

Тем не менее, я до сих пор не понимаю, почему я не мог просто собрать эту библиотеку из чего угодно. Все, что мне нужно, это прототип функции и объектный код, верно? Поскольку я подключаю CRT статически, у меня нет внешних зависимостей. Но когда я пытаюсь связать библиотеку, встроенную в Release под MSVC8, с моим проектом в Debug под MSVC10, у меня возникают эти раздражающие «уже определенные» ошибки компоновщика, которые мы все так ненавидим.

Но почему? Могу ли я просто «инкапсулировать» все эти функции внутри библиотеки и не экспортировать их, чтобы мой проект брал из библиотеки только то, что ему нужно? Почему у меня могут быть предварительно скомпилированные версии libpng и zlib, которые я могу связать в каждом проекте? Да, я думаю, они не построены с использованием MSVC, но все же используют те же функции CRT. Так может ли кто-нибудь подробно объяснить или поделиться ссылкой на какое-то просветленное объяснение этой проблемы?


person Mikhail    schedule 15.03.2012    source источник


Ответы (1)


Поскольку я подключаю CRT статически, у меня нет внешних зависимостей

Что ж, это неправда, у вас действительно есть зависимость. На статической версии ЭЛТ. Debug или Release, в зависимости от ваших настроек сборки. И это внешняя зависимость, компоновщик склеивает CRT позже, когда библиотека будет слинкована. Код, использующий библиотеку, также зависит от CRT. И если параметры компиляции не совпадают, компоновщик ругается.

Вы изолируете эту зависимость, создавая библиотеку DLL вместо статической библиотеки ссылок. Кроме того, вы должны убедиться, что экспортированные функции не вызывают зависимости CRT. Вы не можете вернуть объект C++ из стандартной библиотеки C++ и не можете вернуть указатель на объект, который должен быть освобожден клиентским кодом. Даже передача структур сложна, поскольку их упаковка является деталью реализации, но обычно вам это сходит с рук. Хорошим практическим примером является автоматизация COM, она заставляет вас использовать подмножество универсальных типов. Windows изобилует ими и все эти серверы работают с любой версией компилятора или CRT. Даже любой язык. Однако за это приходится платить, написание такой библиотеки не так просто и удобно, как просто добавить кучу кода в статическую библиотеку.

person Hans Passant    schedule 15.03.2012
comment
Хороший ответ! ... компоновщик склеивает CRT позже, когда библиотека компонуется... - и есть ли способ заставить компоновщика связать функции CRT в .lib? Я могу связать свой собственный код, почему я не могу принудительно связать CRT? - person Mikhail; 15.03.2012
comment
Это не то, как работают статические .lib. Это очень простой формат файла, просто набор файлов .obj. Вы заставляете компоновщика связать CRT, создавая DLL. - person Hans Passant; 15.03.2012