Статическое или динамическое связывание CRT, MFC, ATL и т. д.

StackOverflow https://stackoverflow.com/questions/238465

  •  04-07-2019
  •  | 
  •  

Вопрос

Еще в 90-х годах, когда я впервые начал работать с MFC, я динамически связывал свои приложения и поставлял соответствующие библиотеки DLL MFC.Это вызвало у меня несколько проблем (черт возьми, DLL!), и вместо этого я переключился на статическую компоновку - не только для MFC, но и для CRT и ATL.За исключением больших файлов EXE, статическое связывание никогда не вызывало у меня никаких проблем - есть ли какие-либо недостатки, с которыми сталкивались другие люди?Есть ли веская причина снова вернуться к динамическому связыванию?Сейчас мои приложения в основном STL/Boost.

Это было полезно?

Решение

Есть некоторые недостатки:

  • Больший размер exe-файла (особенно, если вы отправляете несколько exe-файлов)
  • Проблемы с использованием других DLL, которые полагаются на динамическое связывание или предполагают его (например:Сторонние DLL, которые нельзя получить как статические библиотеки)
  • Различные среды выполнения c между DLL с независимой статической связью (без межмодульного выделения/освобождения)
  • Нет автоматического обслуживания общих компонентов (нет возможности заставить стороннего поставщика модулей обновлять свой код для устранения проблем без перекомпиляции и обновления вашего приложения).

Мы делаем статическую компоновку для наших приложений Windows, прежде всего потому, что она позволяет развертывание xcopy, что просто невозможно при установке или использовании SxS DLL таким образом, чтобы это работало, поскольку процесс и механизм плохо документированы или легко удалены.Если вы используете локальные DLL в каталоге установки, это будет работать, но не поддерживается должным образом.Невозможность легко выполнить удаленную установку без использования MSI в удаленной системе является основной причиной, по которой мы не используем динамическую компоновку, но (как вы отметили) у статической компоновки есть много других преимуществ.У каждого есть плюсы и минусы;надеюсь, это поможет их перечислить.

Другие советы

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

Честно говоря, я считаю это недостатками, а не преимуществами.Когда обновляется сторонняя DLL, она может измениться настолько, что может привести к поломке вашего программного обеспечения.И в наши дни место на жестком диске не так ценно, как раньше, лишние 500 КБ в вашем исполняемом файле?Какая разница?

  • Быть на 100% уверенным в версии dll, которую использует ваше программное обеспечение, — это хорошо.
  • Быть на 100% уверенным, что у клиента не будет головной боли от зависимостей, — это хорошо.

На мой взгляд плюсы значительно перевешивают минусы

Пока вы ограничиваете свое использование определенными библиотеками и не используете какие-либо библиотеки DLL, у вас все будет хорошо.

К сожалению, есть некоторые библиотеки, которые нельзя связать статически.Лучший пример, который у меня есть, — OpenMP.Если вы воспользуетесь поддержкой OpenMP в Visual Studio, вам необходимо убедиться, что установлена ​​среда выполнения (в данном случае vcomp.dll).

Если вы используете dll, то вы не сможете передавать некоторые элементы туда и обратно без серьезной гимнастики.std::strings приходит на ум.Если ваш exe и dll динамически связаны, то выделение происходит в CRT.В противном случае ваша программа может попытаться выделить строку с одной стороны и освободить ее с другой.Начинаются плохие дела...

Тем не менее, я все еще статически связываю свои exe и dll.Это действительно уменьшает множество вариантов установки, и я считаю, что некоторые ограничения того стоят.

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

Нет, ничего нового на этом фронте. Так держать.

Совершенно определенно.

Распределение выполняется в «статической» куче. Поскольку выделение освобождения должно выполняться в одной и той же куче, это означает, что если вы отправляете библиотеку, вы должны позаботиться о том, чтобы клиентский код не мог вызвать «ваш» p = new LibClass () и удалить это сам объект, используя delete p; .

Мой вывод: либо защитить выделение и освобождение от клиентского кода, либо динамически связать CRT.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top