Как включить все dll в exe?

У меня есть проект Visual Studio 12; исходный код написан на C ++; это проект OpenCV. Я хочу передать свою скомпилированную программу кому-то другому, но на другом ПК я получаю сообщение об ошибке об отсутствии некоторых DLL. Моя программа использует множество OpenCV (может быть, не только) dll. Как я могу решить эту проблему? Может быть, в VS 12 доступна опция включения всех dll в .exe? Это очень похожий вопрос без правильного ответа: включить библиотеки DLL в Visual Studio c ++ 2008


person Pavlo Zvarych    schedule 24.05.2014    source источник
comment
возможный дубликат MS Visual Studio 2012: сборка статически связанного exe   -  person Joe    schedule 24.05.2014
comment
@LuchianGrigore: Вы не можете связывать библиотеки статически. DLL построена на основе динамического связывания. Да, можно было бы использовать статическое связывание, но для этого вам понадобится статическая библиотека.   -  person datenwolf    schedule 24.05.2014
comment
@datenwolf да, я имел ввиду ссылку статически :)   -  person Luchian Grigore    schedule 24.05.2014
comment
Ответ @Joe, представленный там (на этой странице), мне не помог. Я уже выполнил эти шаги (предоставил Zaw Lin).   -  person Pavlo Zvarych    schedule 24.05.2014


Ответы (4)


Сами библиотеки DLL не могут быть статически связаны с исполняемым файлом; это полностью противоречит их предназначению (ну, на самом деле вы можете использовать некоторые действительно странные уловки вуду, чтобы действительно сделать это, но это не рекомендуется, и вам не следует пробовать его, если вам нужно задать этот вопрос).

Простым решением было бы идентифицировать все библиотеки DLL, которые требуются вашей программе (при простом запуске программы в отладчике будет создан файл журнала, в котором перечислены все эти библиотеки) и скопировать эти библиотеки DLL в тот же каталог, где находится EXE; как это бывает, каталог с EXE-файлом также является первым каталогом, в котором система ищет библиотеки DLL перед переходом к стандартным системным каталогам в конфигурации по умолчанию. Упакуйте его и распределите таким образом.

person datenwolf    schedule 24.05.2014
comment
Я знаю, что это действительно старый пост, но меня очень интересуют странные уловки вуду, чтобы заставить его работать. Вы можете уточнить? - person MooseBoys; 16.11.2017
comment
@MooseBoys: чтобы дать общее представление. При этом необходимо использовать инструмент, похожий на objcopy (возможно, вы даже можете использовать для этого objcopy) или objdump, чтобы как бы разъединить DLL / общий объект с простыми объектными файлами. Однако библиотеки DLL / общие объекты имеют точки входа _1 _ / _ 2_, которые вызываются в определенное время. Также пара специальных разделов для перевода расположения символов. Библиотеки DLL Windows позволяют использовать разделы разделяемой памяти между процессами. и т.п. - person datenwolf; 17.11.2017
comment
@MooseBoys: Другой метод - просто встроить всю DLL / общий объект в виде двоичного объекта в исполняемый файл. После запуска программы эта часть исполняемого файла может быть повторно отображена как виртуальный файл / представление файла и передана в динамический компоновщик как таковой. - person datenwolf; 17.11.2017
comment
@MooseBoys: И еще один метод - реализовать настраиваемый динамический компоновщик в исполняемом файле и позволить ему напрямую работать с двоичным blob встроенной DLL / общего объекта. - За исключением способа удаления / повторного связывания, два других метода просто пугающие (в основном по соображениям безопасности). - person datenwolf; 17.11.2017
comment
Неправильный. Посмотрите на stackoverflow.com/questions/26103966/ - person César Javier Mendoza; 21.05.2018
comment
@ CésarJavierMendoza вопросы и ответы, которые вы связали, касаются статических ссылок. Этот вопрос, однако, касается того, как включить (уже существующие) библиотеки DLL в исполняемый файл. Вы можете связать статически, только если у вас есть статическая библиотека под рукой. Но если все, что у вас есть, это библиотеки DLL, то скучное и простое статическое связывание невозможно. - person datenwolf; 22.05.2018
comment
@Microsoft: в Java это возможно с использованием стандартных технологий MAVEN. Это также возможно на мэйнфрейме SIEMENS BS2000 с использованием BINDER до 2000 года! Для тех, кому интересно, см. BLSSERV на manuals.ts .fujitsu.com / index.php? id = 1-2-12672-13963 / Это один из лучших продуктов для мэйнфреймов, который я никогда не видел. - person schlebe; 28.02.2019
comment
@schlebe: Java всегда поставляется с интерпретатором среды выполнения, а сборки Java не являются собственными исполняемыми файлами. Это ZIP-контейнер, содержащий .java и дополнительные ресурсы. Конечно, в этой ситуации JRE может выполнять всю обработку исполняемых файлов для поддержки этого: загружать DLL из контейнера в адресное пространство процесса и выполнять все перемещения и динамическое связывание. Выполнение JIT-компиляции и загрузка кода в пространство процесса - это описание работы интерпретатора среды выполнения, такого как JRE. - person datenwolf; 28.02.2019
comment
@schlebe: Первоначальный вопрос заключался в том, как встроить DLL (или статически связать ее), если вообще нет интерпретатора среды выполнения. Это совсем другой объем проблемы. А сравнение с другими ОС меняет цели, потому что OP спрашивает о конкретной ОС, а маркетинг других систем здесь не помогает. - person datenwolf; 28.02.2019

более сложным решением было бы создать статические библиотеки opencv из src, а затем связать вашу программу с ними, в результате чего получится 1 большой двоичный исполняемый фрагмент, который не использует никаких dll (кроме ffmpeg, не уверен в этом).

для создания статических библиотек вам нужно запустить cmake с: BUILD_SHARED_LIBS = OFF

но перед этим сделайте глубокий вдох. связывание вашей программы будет значительно сложнее, потому что теперь вам нужно вручную связать все zlib, libpng и любые зависимости (которые раньше были удобно связаны с вашими dll)

Опять же, самое простое решение - развернуть все DLL opencv вместе с вашей программой.

person berak    schedule 24.05.2014

Вы можете использовать Windows Dependency Walker, чтобы определить, какие библиотеки DLL необходимо запускать вашей программе.

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

person Ferruccio    schedule 24.05.2014

Если вы выберете общепринятое решение (упакуйте библиотеки DLL в EXE-файл) и не хотите беспокоиться о том, какие библиотеки DLL использовать, то вы можете скопировать все библиотеки DLL OpenCV. Они не такие большие (65 МБ на OpenCV 2.43). Они расположены по адресу ...\opencvXXX\build\x64\vc10\bin\

где XXX - версия OpenCV. Вы можете использовать x64 или x86 в зависимости от вашей платформы (32 или 64-разрядной). И версия vc в вашей системе может быть другой (vc9, vc10 и т. Д.)

person Hazem    schedule 04.10.2017