Должен ли я ссылаться на среду выполнения Visual Studio C статически или динамически? - PullRequest
19 голосов
/ 24 апреля 2009

Я прочитал аргументы с обеих сторон о том, следует ли статически или динамически ссылаться на библиотеку времени выполнения C в проектах Visual Studio, и я до сих пор не совсем уверен, что и думать.

Мой проект использует некоторые сторонние библиотеки (Python, HDF5, Trilinos и Microsoft MPI), каждая из которых должна быть построена из той же библиотеки времени выполнения, что и мой последний исполняемый файл (в противном случае они не могут быть связаны друг с другом). При статическом связывании каждая из этих библиотек будет содержать копию среды выполнения C. Я читал, что это может вызвать проблемы, потому что конечный исполняемый файл будет содержать несколько копий среды выполнения, ни одна из которых не может взаимодействовать друг с другом. Но не будет ли компоновщик жаловаться, если одни и те же символы были определены несколько раз?

Я бы хотел избежать "DLL Hell", но беспокоюсь о коварных ошибках, которые могут возникнуть из-за статического связывания в нескольких копиях среды выполнения. Я неправильно читаю?

Кроме того, я использую Visual Studio 2005 и прочитал, что среда выполнения с пакетом обновления 1 не имеет обратной совместимости. Означает ли это, что приложение, созданное без SP1, не будет работать на компьютере с dll SP1, даже если они имеют одинаковые имена (например, msvcr80.dll)?

Ответы [ 4 ]

25 голосов
/ 25 апреля 2009

Статическое связывание раздувает все ваши EXE-файлы и DLL и может привести к сбоям (например, если код в одной DLL вызывает free () с указателем, выделенным функцией malloc () в другой DLL).

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

См. Подробности в разделе «Развертывание библиотек DLL Visual C ++ в виде закрытых сборок» по адресу http://msdn.microsoft.com/en-us/library/ms235291(VS.80).aspx, но в основном ваше приложение выглядит так:

c:\Program Files\My App\MyApp.exe
c:\Program Files\My App\MyLibrary.dll
c:\Program Files\My App\Microsoft.VC80.CRT\Microsoft.VC80.CRT.manifest
c:\Program Files\My App\Microsoft.VC80.CRT\msvcr80.dll

Что касается вашего последнего вопроса, да, целевой машине для работы требуются правильные версии DLL-библиотек времени выполнения, но, развертывая их как частные сборки, вы гарантируете это.

Еще одним преимуществом является то, что пользователи, не являющиеся администраторами, могут устанавливать ваше приложение (не в Program Files, а в другом месте) - им не нужно разрешение для записи файлов в область WinSxS.

12 голосов
/ 25 апреля 2009

Единственный раз, когда вы получите несколько копий среды выполнения, это когда вы статически связываете библиотеку с DLL - каждая DLL получит копию, а также исполняемый файл. Если они все статические библиотеки, а не библиотеки DLL, все они будут связаны друг с другом, и все ваши библиотеки будут иметь одинаковое время выполнения.

Это работа компоновщика.

2 голосов
/ 24 апреля 2009

... Делайте это статически ... попытки исправить DLL Ад не сработал так хорошо ... просто добавьте дополнительные 200 КБ к вашей установке со статической связью.

1 голос
/ 24 апреля 2009

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

...