首页 > 其他分享 >CMake链接DLL可行实践

CMake链接DLL可行实践

时间:2024-01-16 19:44:27浏览次数:24  
标签:文件 IMPORTED lib 导出 DLL CMake 链接

DLL作为Windows下的动态库格式,其同Linux等平台的动态库稍有不同,比如对MSVC编译器需要导出符号等。本文简述一种情况,即仅有dll文件及对应头文件时应当如何在CMake中完成链接。

首先必须提示的一点是,DLL文件是程序运行时会调用的文件。编译器在编译链接时并不关心DLL文件在哪,而是会去查找DLL文件的导出库。该导出库记载了DLL中所有暴露的导出符号(类、函数、变量等),以提供给其它程序调用使用。编译器会根据指令链接该导出库到程序,随后程序运行时方才会去查找DLL文件中对应符号所记载的内容(函数中的程序、类的内容、变量的值等)。

Windows下,这个导出库同静态库一样是以.lib作为后缀名的。MSVC在编译时会同时输出dll和这个.lib文件。一般动态库的开发者会同时发布DLL、LIB、头文件给用户使用。而有时我们可能只能获取到DLL和头文件。这种情况下,我们可以使用工具重新生成.lib链接库用于链接。可行实践是使用两个工具,gendef和lib。前者在绝大多数MinGW64包中提供;后者在MSVC套件中提供,安装Visual Studio即可在开发者命令行中使用。

首先,我们使用gendef获取DLL文件中的所有导出符号,并以特定格式保存至一种.def文件中:

gendef <DLL文件名.dll>

程序会输出一个与DLL同名的def文件。该文件记载了DLL文件中所有导出的符号。这些符号同样可以使用MSVC工具dumpbin列出。

接下来,我们根据def文件中所记载的导出符号生成lib导出库:

lib /def:<DEF文件.def> /machine:x64 /out:<DLL文件名.lib>

machine即为希望编译的目标平台架构。

现在我们可以在CMakeLists.txt中尝试链接该库了。在本实践中,我们尝试将其注册为CMake对象:

add_library(库名 SHARED IMPORTED)
set_target_properties(库名 PROPERTIES
	IMPORTED_LOCATION DLL文件路径/DLL文件名.dll
	IMPORTED_IMPLIB LIB文件路径/LIB文件名.lib
)
target_link_libraries(程序名 库名)

提醒注意的是,set_target_properties所设置的IMPORTED_LOCATIONIMPORTED_IMPLIB属性不支持相对路径,而必须使用绝对路径,否则可能导致Ninja等构建系统报错找不到链接的程序位置。但在CMakeLists.txt中写绝对路径绝对不是一个好主意,毕竟您需要分发您的项目给别人使用。一个好办法是使用${CMAKE_SOURCE_DIR}宏。该宏记录了CMakeLists.txt所在的绝对路径,只需借此添加相对位置即可,例如:

add_library(库名 SHARED IMPORTED)
set_target_properties(库名 PROPERTIES
	IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/external/DLL文件名.dll
	IMPORTED_IMPLIB ${CMAKE_SOURCE_DIR}/external/LIB文件名.lib
)
target_link_libraries(程序名 库名)

这样我们便成功链接DLL了。在项目中include库的头文件,就可以使用了。其它的一些可能的情况如下:

  1. 无法解析的外部符号。如果实在查不出问题来,需要怀疑您链接的DLL是用MinGW GCC编译的,而不是MSVC。这种情况下MSVC无法直接链接使用MinGW编译的DLL。可换用MinGW尝试解决或动用一些方法转为MSVC DLL。后者暂不在本文讨论范围内。

  2. 务必注意,这样做程序会优先根据IMPORTED_LOCATION所给出的位置查找DLL。故在本机上运行,不把DLL复制到程序根目录也不会报错。但如果将程序放到其它计算机上使用,就会导致找不到DLL文件而报找不到DLL或0xc000007b。故此不要忘记将DLL复制到程序目录下。CMake的install指令可以协助完成这一工作。

标签:文件,IMPORTED,lib,导出,DLL,CMake,链接
From: https://www.cnblogs.com/izwb003/p/17968408/cmake_link_dll_practice

相关文章

  • VSCode配置多目录CMake项目
    多目录CMake项目指一个workspace下有多个CMake项目,不需要使用CMakeTool插件修改tasks.json,添加cmake,按照clean->cmake->make的顺序执行tasks.json {"version":"2.0.0","options":{"cwd":"${fileDirname}/build"},......
  • 网址链接跳转外部安全提醒代码
    网页的安全性优化是一个越来越被开发者重视的问题,当本站链接点击跳转到第三方外链接时,要弹框提示信息,需要支持jquery引用。<!DOCTYPEhtml> <html> <head> <metahttp-equiv="Content-Type"content="text/html;charset=UTF-8"> <metahttp-equiv="X-UA-Compat......
  • 《c++dll篇》VS2019生成dll及调用
    VS2019生成dll及调用生成DLL1.创建dll工程2.编写dll函数经过上述过程后工程中会生成几个自带的文件,可以自行创建或者更名,我直接在上面进行编写了。如下我先在pch.h中创建我需要调用函数的声明,他们分别用于实现加法和取最大值的功能,你可以根据自己的需求更改成自己的子程序。......
  • 《c++dll篇》VS2015生成dll及调用
    VS2015生成dll及调用原文链接:https://blog.csdn.net/qq_20792765/article/details/109801411创建DLL文件创建的DLL文件包括三个文件(.h/.dll/.lib),1、打开VS新建一个项目。2、选择DLL,附加选项选择空项目3、在头文件和源文件下分别添加如下文件4、在头文件CaculatorDLL.h......
  • 《c++dll篇》VS2008生成dll及调用
    VS2008生成dll及调用原文链接:https://www.cnblogs.com/Ich-Sun/p/6593703.html生成dlladd.h里面的代码:#ifndefDlladd_H_#defineDlladd_H_#ifdefMYLIB#defineMYLIBextern"c"_declspec(dllimport)#else#defineMYLIBextern"C"_declspec(dllexport)#e......
  • 轻松导航:教你在Excel中添加超链接功能
    前言超链接是指在网页或电子文档中常见的元素,它的主要作用是将一个文本或图像与另一网页、文件或资源链接起来,从而使用户能够通过点击该链接跳转到目标资源、超链接可以起到导航以及引用的作用。超链接通常有以下几种用途:网页链接文档链接内部定位链接电子邮件链接在Java......
  • [Python急救站]学生管理系统链接数据库
    相信很多人在初学Python的时候,经常最后作业就是完成一个学生管理系统,但是我们来做一个完美的学生管理系统,并且将数据储存到数据库里。我们先看看我们的数据库怎么设置。首先呢,我选择用的是SQLServer然后,我们的数据库名称为学生管理系统 接着,新建一张表,我设置表的名称为学生......
  • 动态链接库的生成和使用
    1、当前目录/home/xuanmiao/Demo/LSPT/Test创建文件prime.h和prime.cprime.hintisprime(longintnumber);prime.cintisprime(longintnumber){longintj;intprime=1;/*Testifthenumberisdivisible,starting*from2*/for(j=2;......
  • 探索短链接:让网络分享更便捷
    短链接是一种将长网址缩短为简洁形式的编码,它在互联网领域具有广泛的应用。本文将从多个方面介绍短链接的原理、类型、优势及应用场景,帮助您深入了解这一重要的网络技术。短链接|一个覆盖广泛主题工具的高效在线平台(amd794.com)https://amd794.com/shorturl一、短链接简介......
  • 【CMake】5. 单项目多模块添加第三方依赖示例工程
    CMake示例工程代码https://github.com/LABELNET/cmake-simple单项目单模块示例工程https://github.com/LABELNET/cmake-simple/tree/main/simple-mod-deps这里引入C++gRPC依赖,进行示例1.多模块工程+第三方依赖CMake多模块工程,这是一个示例工程simple-mod-deps,项目名称de......