为什么我的程序要求OpencV的.dll,即使我静态链接其.lib

时间:2016-07-26 14:30:54

标签: c++ visual-studio opencv cmake static-linking

我正在构建一个使用OpenCV 3.1和CMake 3.5以及Visual Studio 2015 x64的小程序。

我链接到OpenCV的.lib文件,但是当我尝试运行该程序时,我收到有关丢失的DLL的错误:

MyApp.exe: error while loading shared libraries: opencv_world310d.dll: cannot open shared object file: No such file or directory

这是我的CMakeLists.txt

cmake_minimum_required(VERSION 3.5)
project (MyProj)

set(CMAKE_FIND_LIBRARY_SUFFIXES, ".lib")

#Boost
set(Boost_USE_STATIC_LIBS        ON)
set(Boost_USE_MULTITHREADED      ON)
set(Boost_USE_STATIC_RUNTIME    OFF)
find_package(Boost REQUIRED system thread serialization filesystem)

#OpenCV
find_package(OpenCV REQUIRED)

add_executable(
        MyApp
        main.cpp
)

target_include_directories(MyApp PRIVATE
        ${OpenCV_INCLUDE_DIRS}
        ${Boost_INCLUDE_DIRS}
)

target_link_libraries(MyApp
        ${OpenCV_LIBRARIES}
        ${Boost_LIBRARIES}
)

OpenCV_DIR设置为C:\tools\opencv3\build\x64\vc14\libinclude/ opencv_world310.lib opencv_world310d.lib OpenCVConfig.cmake OpenCVModules.cmake OpenCVModules-debug.cmake OpenCVModules-release.cmake已从OpenCV v3.1的官方Windows二进制文件中提取

然后我使用cmake . -G "Visual Studio 14 Win64"

生成VS解决方案

如您所见,OpenCV lib已添加到依赖项中: enter image description here

用于链接步骤:

Link:
  C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64\link.exe /ERRORREPORT:QUEUE /OUT:"C:\...\Debug\MyApp.exe" /
  INCREMENTAL /NOLOGO kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib 
  advapi32.lib C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib 
  C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib 
  C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib 
  C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib 
  C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib 
  C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib 
  C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib 
  C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib 
  C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib "C:\tools\boost_1_61_0\stage\lib\libboost_system-vc140-mt-gd-1_61.lib" 
  "C:\tools\boost_1_61_0\stage\lib\libboost_thread-vc140-mt-gd-1_61.lib" 
  "C:\tools\boost_1_61_0\stage\lib\libboost_serialization-vc140-mt-gd-1_61.lib" 
  "C:\tools\boost_1_61_0\stage\lib\libboost_filesystem-vc140-mt-gd-1_61.lib" 
  "C:\tools\boost_1_61_0\stage\lib\libboost_chrono-vc140-mt-gd-1_61.lib" 
  "C:\tools\boost_1_61_0\stage\lib\libboost_date_time-vc140-mt-gd-1_61.lib" 
  "C:\tools\boost_1_61_0\stage\lib\libboost_atomic-vc140-mt-gd-1_61.lib" /MANIFEST /MANIFESTUAC:"level='asInvoker' 
  uiAccess='false'" /manifest:embed /DEBUG /PDB:"C:/Users/.../Debug/MyApp.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /
  IMPLIB:"C:/Users/.../Debug/MyApp.lib" /MACHINE:X64  /machine:x64 MyApp.dir\Debug\sheepface.obj MyApp.dir\Debug\source.obj
  MyApp.vcxproj -> C:\Users\...\Debug\MyApp.exe
  MyApp.vcxproj -> C:/Users/.../Debug/MyApp.pdb (Full PDB)

我已经尝试过设置魔法变量

set(OpenCV_STATIC ON)
set(BUILD_SHARED_LIBS     OFF)

但他们没有区别

1 个答案:

答案 0 :(得分:2)

您有三种不同的选择来创建和使用库;静态,动态隐式和动态显式。 library.lib不一定是静态库,它将包含您期望的编译代码。它包含代码或(简单地说)包含所需的 * .dll 的名称,由OS加载,并且该条目指向此dll中的函数。如果你不知道特定库是什么类型的lib,你可以使用

lib /list foo.lib

(参见here)确定lib的类型。如果它是静态库,它将显示创建lib时使用的一些 .obj 文件。如果是导入库,它将显示您应提供的所需 .dll 。 dll本身应该在其中一个搜索路径中。如果要使用某些特殊路径,它可能会变得非常复杂,但最简单的方法是将其放入与使用它或系统文件夹的可执行文件相同的文件夹中。请阅读Dynamic-Link Library Search Order了解更多详情。静态lib和隐式动态都需要头文件和.lib文件。

第三种方式(动态显式)您必须使用LoadLibrary[AW]GetProcAddressFreeLibrary。在这里指定dll的路径并直接使用dll""。您没有任何标题或.lib文件,但必须知道完全如何命名函数以及如何声明这些函数(返回值和参数值类型),否则您的程序将赢得&#t; t按预期工作。

您可以在MSDN上找到有关dll的更多信息。