2012-03-15 2 views
2

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

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

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

ответ

3

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

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

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

+0

Хороший ответ! «... компоновщик склеивает CRT позже, когда библиотека связывается ...» - и есть ли способ заставить компоновщика связывать функции CRT в .lib? Я могу связать свой собственный код, почему я не могу заставить CRT связываться? – Mikhail

+1

Это не то, как работают статические .libs. Это очень простой формат файла, просто коллекция файлов .obj. Вы вынуждаете компоновщик связывать ЭЛТ, создавая DLL. –