Как я могу избавиться от проблем с отсутствующими DLL?


15

Я сделал несколько игр с Visual C ++ 2015 и OpenGL. Когда я запускал его на своей машине, проблем не было, но когда я запускал его на других машинах, это показывает, что некоторые библиотеки DLL отсутствуют. Я хочу знать, как убедиться, что это не произойдет в следующий раз, и что я должен учитывать, чтобы избежать проблем с отсутствующими файлами?


8
Во-первых, убедитесь, что вы создаете версию выпуска.
user253751

3
Если вы хотите быть абсолютно уверены, что нет никаких зависимостей от самой VS - но она имеет свой собственный недостаток - в настройках генерации кода вы можете выбрать многопотоковую / многопоточную отладку (для отладочных сборок) вместо MT DLL / MT Debug DLL . Это увеличивает размер исполняемого файла, и ваш двоичный файл, скомпилированный таким образом, не получит выгоду от обновлений dll во время выполнения. Но это зависит от вас. Плюс в том, что ваш исполняемый файл не будет иметь «внешних» зависимостей. Я не буду публиковать это как ответ, потому что это не решение вашей проблемы, а просто обходной путь.
Gizmo

@Gizmo обходной путь - все еще ответ, и комментарии временны и используются, чтобы разъяснить посты, в которых они находятся, и могут быть удалены. Так что, если это полезно, вы должны опубликовать это как ответ.
user1306322

Хм хорошо. Я отправлю это как ответ тогда.
Gizmo

Ответы:


22

Вам необходимо установить распространяемые файлы для версии Visual Studio, которую вы использовали, на любой компьютер, на котором нужно запустить исполняемые файлы, например, https://www.microsoft.com/en-us/download/details.aspx?id=48145 для VS2015. , Вам также может понадобиться переадресация для DirectX или других компонентов.

Установщики приложений, как правило, устанавливают все распространяемые файлы для любых своих зависимостей. Вы можете сделать такой установщик с помощью InnoSetup, NSIS, WIX или различных других инструментов.

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


Можно ли использовать VS для создания такого установщика? Я думал, что однажды увидел что-то под названием OneClick в настройках проекта.
user1306322

@ user1306322: абсолютно, одно решение было упомянуто в комментариях вопроса Gizmo. Вопрос только в том, на какие среды исполнения / DLL вы ссылаетесь. В настройках по умолчанию вы связываетесь с библиотекой CRT, зависящей от версии, но это можно изменить, перебрав опции компоновщика. Просто используйте ссылку MSVCRT.DLL(включена в саму Windows) вместо MSVCPxxx.DLL(версии для конкретной версии, включенные в выпуски Visual Studio).
Шон

Или, если вы имеете в виду создание полного установщика, это в основном и есть WIX . Это типичный чрезмерно сложный XML-тяжелый Microsoft Crapfest, но он работает. Раньше также были «проекты для инсталляторов», хотя я считаю, что они исчезли с 2013 или 2015 года.
Шон

7

Я использую Dependency Walker для отслеживания отсутствующих DLL:

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


В VS также есть опция времени компиляции для статической связи DLL:

  • Статическое связывание означает, что библиотеки DLL включены в файл EXE.
  • Статическое связывание увеличивает размер файла EXE.
  • Статическое связывание означает, что эта версия DLL всегда будет использоваться.
  • Однако статическое связывание также означает, что у вас никогда не будет проблем с отсутствующими DLL.

1
Зависимость ходока довольно старая. Он больше не эмулирует механизмы Windows для загрузки DLL. Часто приводит к поддельным сообщениям о невозможности найти DLL.
jpmc26

И статическое связывание может быть запрещено в лицензии зависимости.
KeyWeeUsr

6

Для Visual C ++ у вас есть несколько вариантов обработки перераспределения: запустите EXE из вашего установщика (с правами администратора), используйте модуль слияния MSM с вашим установщиком MSI или даже параллельные библиотеки DLL. Смотрите MSDN для деталей.

Большая проблема - OpenGL. Единственная версия OpenGL, включенная в Windows, - это программный рендерер OpenGL 1.5. Все остальное требует установки стороннего ICD.

Это одна из причин, по которой многие игры для Windows используют DirectX, поскольку они включены в операционную систему. См. « Развертывание Direct3D 11 для разработчиков игр» и « Не такая прямая настройка» .


1
Рекомендации OpenGL устарели - каждый современный графический драйвер поставляется с современной OpenGL ICD.
user253751

Мне лично пришлось устанавливать библиотеки openGL на машины всего лишь год назад
Gnemlock

@ Gemmlock Сразу после переустановки Windows на указанном летнем компьютере, вы можете быть правы. Вы продолжали видеть эту проблему после установки официального пакета драйверов от NVIDIA, AMD или Intel?
Дамиан Йеррик

2
@Gnemlock - если вы вручную устанавливаете библиотеки OpenGL, вы делаете что-то ужасно неправильно. Если вы на самом деле имеете в виду «установить драйвер вашего производителя GPU», то это именно то, что только что сказал immibis.
Максимус

@ Гнемлок - ах, значит, не имеет отношения к реальному миру. Спасибо за разъяснение.
Максимус

1

Отказ от ответственности: это обходной путь , а не решение вашего ответа, но все же очень жизнеспособная возможность.

Если вы хотите быть абсолютно уверены, что нет никаких зависимостей от самой VS - но у нее есть свои недостатки - в настройках генерации кода вы можете выбрать Multi-Threaded (MT) / Multi-Threaded Debug (MD) (для отладочных сборок). ) вместо MT DLL (MTd) / MT Debug DLL (MDd).

введите описание изображения здесь

Какие недостатки?

  • Это увеличивает размер исполняемого файла и двоичного файла (хотя, если вы создаете игру, это, вероятно, незначительно)
  • скомпилированные таким образом не выиграют от обновлений dll во время выполнения. (например, если Microsoft выпускает VC ++ 2015 SP2, SP3, SP4 и т. д.) Но это зависит от вас.
  • Большее использование ОЗУ (также незначительное), потому что вы не используете повторно существующий / загруженный код (DLL)
  • Вы должны быть уверены, что все библиотеки, на которые вы ссылаетесь, скомпилированы для одной и той же среды выполнения, иначе может произойти сбой связывания или могут возникнуть интересные ошибки времени выполнения (возможно, нет, но это случалось со мной один раз в жизни в устаревшем проекте, который был обновлен до новейшая VS)

А какие плюсы?

  • Ваш исполняемый файл не будет иметь «внешних» зависимостей от самой VS (не требуется msvc * .dll).
  • некоторые люди видят в этом увеличение производительности, потому что вы устраняете накладные расходы на вызовы DLL, хотя это теоретически верно, на практике улучшения незначительны

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

Другой обходной путь - поместить все необходимые библиотеки DLL туда, где находится ваш бинарный файл. Ваше приложение не получит выгоду от обновлений (для библиотек времени выполнения), но это все.

Реальным решением является распространение приложения в режиме dll выпуска / без отладки (MTd) и предоставление правильного распространяемого установщика VC ++ (и любых других установщиков библиотеки, которые вы можете использовать, например, OpenAL, DirectX9, PhysX), и позволить пользователю запустить перед запуском приложения (как указано в других ответах).

Также убедитесь, что пользователь знает, что ему / ей может понадобиться обновить драйверы графического процессора (поскольку они содержат несколько сред выполнения для многих приложений, например, OpenGL, Vulcan).


0

Моим решением было скопировать и вставить DLL, которая вызвала ошибку, в папку, где находится файл .sln в visual studio. После #includeраздела я написал #pragma comment (lib, "lost DLL name with .dll")и решил это!

Примечание. Я решил проблему, с которой столкнулся при работе со сторонней библиотекой (vulkan api) DLL. Может быть, это не известно, но 90% будут работать удачи :)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.