Как обнаружить дополнительные зависимости DLL в Cassablanca (cpprestsdk) в CMake - PullRequest
1 голос
/ 14 марта 2019

Это мой самый первый пост, так что терпите меня. Вот мои настройки:

Я недавно начал использовать Cassablanca (cpprestsdk) в 64-битной Windows 10.

Я использую менеджер пакетов Microsoft (vcpkg):

https://github.com/Microsoft/vcpkg

Я не использую Visual Studio, хотя использую ее компилятор. Я создал проект CMake, который создает библиотеку DLL, которая по существу использует проект вступления из cpprestsdk: https://github.com/Microsoft/cpprestsdk/wiki/Getting-Started-Tutorial

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

Теперь я обыскал все вокруг и уже понял, как заставить это работать.

Другая DLL просто связывается с этой новой DLL и вызывает интересующую меня функцию.

После некоторых поисков я обнаружил, что моя новая DLL должна быть связана со следующим:

target_link_libraries (ЧАСТНЫЕ cpprestsdk :: cpprest cpprestsdk :: cpprestsdk_zlib_internal cpprestsdk :: cpprestsdk_boost_internal cpprestsdk :: cpprestsdk_openssl_internal)

Больше поиска, и я обнаружил, что мне нужно указать расположение zlib и openssl:

набор (ZLIB_ROOT "$ {VCPKG_HOME_WIN} / zlib_x64-windows") set (OPENSSL_ROOT_DIR "$ {VCPKG_HOME_WIN} / openssl-windows_x64-windows")

Это все хорошо, работает отлично. Затем я пришел, чтобы повысить. При установке cpprestsdk с vcpkg он достаточно умен, чтобы загружать все надстройки, которые ему когда-либо понадобятся, поэтому существует множество надстроечных каталогов с кучей DLL.

Когда я пытался вызвать функцию из моей DLL из прежнего приложения, DLL не удалось загрузить, потому что он не мог найти свои DLL зависимостей. Я скопировал поверх библиотек restsdk, openssl и zlib в унаследованное приложение, но я не знал, какие DLL-файлы boost скопировать. Очевидно, я мог бы выстрелить в него и просто скопировать все dll-бусты, которые vcpkg скачал как часть restsdk, но это похоже на перебор.

Наконец, я не был уверен, что делать, поэтому я построил весь проект CMake в Visual Studio. Так или иначе Visual Studio был достаточно умен, чтобы понять это, и в выходной каталог моего проекта он поместил следующие надбавки DLL:

boost_date_time-vc141-мт-Г.Д.-x32-1_68.dll boost_system-vc141-мт-Г.Д.-x32-1_68.dll

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

Незнакомец все же, я решил взять каждого из них, чтобы посмотреть, действительно ли они оба нужны. Оказывается, все работает нормально, если я удалил dll boost_system, но не если я удалил dll boost_date_time.

Итак, в конце концов, единственное, что мне нужно, это boost_date_time, так что кажется, что даже Visual Studio был не прав.

Наконец, это подводит нас к моему вопросу, как в мире я должен точно определить, какая dll нужна моему проекту CMake, когда единственное, на что я могу перейти - это то, что cpprestsdk нуждается в повышении с помощью этого оператора?

target_link_libraries (PRIVATE cpprestsdk :: cpprest cpprestsdk :: cpprestsdk_zlib_internal cpprestsdk :: cpprestsdk_boost_internal cpprestsdk :: cpprestsdk_openssl_internal)

Полагаю, я надеюсь, что ответ не «это зависит» от того, какие функции boost на самом деле вызывает мой код, и я не знаю ответа на него, потому что я не знаю, какие функции boost на самом деле вызывает cpprestsdk. на том, что функции cpprestsdk мой код вызывает.

Спасибо за ваше время.

Весь файл CMake выглядит следующим образом:

cmake_minimum_required(VERSION 3.7)

include(GenerateExportHeader)

include_directories(${CMAKE_BINARY_DIR})

project(mydll)

set(mydll.SOURCES <source files>)

add_library(mydll SHARED ${mydll.SOURCES})

generate_export_header(mydll
                       BASE_NAME mydll_exports 
                       EXPORT_MACRO_NAME mydll_EXPORTS
                       EXPORT_FILE_NAME mydll_EXPORTS.h
                       STATIC_DEFINE mydll_EXPORTS_BUILT_AS_STATIC)

find_package(cpprestsdk CONFIG REQUIRED)

target_link_libraries(mydll PRIVATE cpprestsdk::cpprest
cpprestsdk::cpprestsdk_zlib_internal
cpprestsdk::cpprestsdk_boost_internal
cpprestsdk::cpprestsdk_openssl_internal)

Ответы [ 2 ]

0 голосов
/ 14 марта 2019

Я думаю, что инструмент DependencyWalker (зависит.exe) является правильным ответом для этого.

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

0 голосов
/ 14 марта 2019

Хм, возможно я частично разобрался с ответом. Утилита 'dumpbin' с Visual Studio может частично сделать это за вас:

Изображение имеет следующие зависимости:

HTTPAPI.dll  
WINHTTP.dll  
bcrypt.dll  
CRYPT32.dll  
boost_date_time-vc141-mt-gd-x64-1_69.dll  <- I had to add this
SSLEAY32.dll  <- I had to add this
LIBEAY32.dll  <- I had to add this
zlibd1.dll  <- I had to add this
KERNEL32.dll  
MSVCP140D.dll  
CONCRT140D.dll  
WS2_32.dll  
VCRUNTIME140D.dll
ucrtbased.dll

Проблема здесь даже в том, что это не идеальный ответ, потому что я не добавил, и при этом у меня нет httpapi.dll, winhttp.dll, bcrypt.dll и crypt32.dll. Это только вероятно работает, потому что ни один из моего кода на самом деле не вызывает функции из этих библиотек Если они действительно необходимы, то менеджер vcpkg должен был бы также загрузить их как зависимости, но это не так, поэтому у меня нет возможности получить их в текущей среде. Я до сих пор не удовлетворен этим ответом.

...