2009-04-24 3 views
17

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

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

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

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

ответ

23

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

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

Смотрите раздел «Развертывание Visual C++ библиотеки DLLs как частные собрания» в 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 

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

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

+0

Это ответ, который я искал. Кажется, что частные сборки - самое безопасное решение моей проблемы. Напомните мне пакеты Mac, в которых приложение распространяется в фиксированной структуре каталогов. Благодаря! – user76293

+6

Но частные сборки не будут исправлены Windows Update, правильно? Таким образом, вам нужно будет сохранить свою копию библиотеки времени выполнения в актуальном состоянии самостоятельно. См. Также http://blogs.msdn.com/larryosterman/archive/2004/04/29/123090.aspx –

+0

Я никогда не получал эти частные сборки, если моя папка «Приложение» (My App) содержит сочетание 32-разрядных и 64-битные приложения. Вы не можете просто добавить что-то вроде x32 или x64 в имя папки сборки, а это значит, что вы можете использовать только частные сборки, если у вас есть только 32-разрядные или только 64-разрядные приложения. – Patrick

0

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

+0

Чтобы уточнить: я не связываю библиотеки друг с другом, и я не получаю многозначные символы, когда я связываю свой основной исполняемый файл. Но я не уверен, есть ли в моем исполняемом файле несколько экземпляров исполняемой программы C, что происходит, когда вы ссылаетесь на нее статически (согласно моей интерпретации прочитанного, что может быть неправильным). – user76293

2

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

+0

Любые мысли о множественных копиях среды выполнения? Это мой реальный вопрос. – user76293

+0

В любом случае будет много копий среды выполнения. Вот для чего предназначена папка WinSxS (и это попытка исправить DLL Hell). Это запутанно, так что упаковка вашей собственной среды выполнения позволит избежать таких проблем. – CookieOfFortune

11

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

Это работа линкера.