这是我的第一篇文章,所以请耐心等待。这是我的设置:
我最近开始在Windows 10 64bit上使用Cassablanca(cpprestsdk)。
我正在使用Microsofts包管理器(vcpkg):
https://github.com/Microsoft/vcpkg
虽然我正在使用它的编译器,但我没有使用Visual Studio。我创建了一个CMake项目,它创建了一个DLL,它基本上使用了cpprestsdk中的intro项目:https://github.com/Microsoft/cpprestsdk/wiki/Getting-Started-Tutorial
最终目标是我希望从遗留应用程序中的另一个现有DLL调用我正在创建的这个DLL。
现在我已经四处寻找,我已经想出了如何使这项工作。
另一个DLL只是链接这个新的DLL并调用我感兴趣的函数。
经过一番搜索,我发现我的新DLL需要链接以下内容:
target_link_libraries(PRIVATE cpprestsdk :: cpprest cpprestsdk :: cpprestsdk_zlib_internal cpprestsdk :: cpprestsdk_boost_internal cpprestsdk :: cpprestsdk_openssl_internal)
更多搜索,我发现我需要指定zlib和openssl的位置:
set(ZLIB_ROOT“$ {VCPKG_HOME_WIN} / zlib_x64-windows”)set(OPENSSL_ROOT_DIR“$ {VCPKG_HOME_WIN} / openssl-windows_x64-windows”)
这一切都很好,工作得很好。然后我来提升。使用vcpkg安装cpprestsdk时,它足够聪明,可以下载所需的所有提升,因此有大量的DLL提升目录。
当我尝试从遗留应用程序从我的DLL调用函数时,DLL无法加载,因为它无法找到其依赖项DLL。我将restsdk,openssl和zlib dll复制到遗留应用程序,但我不知道要复制的dll是什么。显然我可以霰弹枪,并简单地复制vcpkg作为restsdk的一部分下载的所有增强dll,但这看起来有点矫枉过正。
最后我不知道该怎么做,所以我在Visual Studio中构建了我的整个CMake项目。不知怎的,Visual Studio很聪明,可以解决这个问题,在我的项目的输出目录中,它放置了以下boost DLL:
boost_date_time-vc141-mt-gd-x32-1_68.dll boost_system-vc141-mt-gd-x32-1_68.dll
所以我想我会拍摄一下,然后我将这些图书馆复制过来,看哪,一切正常。遗留DLL成功加载了我的DLL,因为它具有所有正确的依赖项。
更奇怪的是,我决定把每一个都拿出来看看它们是否真的需要它们。事实证明,如果我删除boost_system dll,一切正常,但如果我删除了boost_date_time dll则没有。
所以在一天结束时,我需要的唯一提升dll是boost_date_time,所以看起来甚至Visual Studio都错了。
最后,我们提出了一个问题,在世界上我应该弄清楚我的CMake项目究竟需要哪个dll,而我唯一能做的就是cpprestsdk需要通过这个语句来提升?
target_link_libraries(PRIVATE cpprestsdk :: cpprest cpprestsdk :: cpprestsdk_zlib_internal cpprestsdk :: cpprestsdk_boost_internal cpprestsdk :: cpprestsdk_openssl_internal)
我想我希望答案不是'这取决于'我的代码实际调用的提升函数,我不知道答案,因为我不知道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)
嗯,我可能已经部分找到了答案。 Visual Studio的'dumpbin'实用程序可以部分为您执行此操作:
Image具有以下依赖项:
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管理器应该也可能已经将它们作为依赖项下载了,但事实并非如此,我无法在当前环境中获取它们。我仍然不满意这个答案。
我认为工具DependencyWalker(depends.exe)是正确的答案。
它显示所有其他dll都是系统dll,我的应用程序可能正在从系统加载它们,而我需要添加的dll,当我在cpprestsdk_2_10d.dll上使用它时,它显示这些dll缺少依赖项。这就是我所追求的,这就是我真正需要用dll打包以解决这些依赖性问题的dll。我想我会继续把这个标记为答案。