• VS生成动态库(VS2022、CUDA、Lib)


    VS2022 CUDA工程需要编译成动态库并提供出去,记录一下如何生成动态库。

    一、VS创建动态库

    1、创建空项目

    虽然VS有动态链接库的模板,但是个人感觉使用空项目更加方便。
    按照下图,选择空项目,下一步。
    00·-创建空项目
    指定项目名称和位置,另外建议勾选“将解决方案和项目放在同一目录中”,创建。
    002-创建空项目

    如下图,空项目TestMakeLib创建成功。
    003-创建空项目

    2、配置项目属性为动态库

    选中TestMakeLib(上图红色框),右键菜单—>属性,打开工程属性页
    按照下图选项,将配置类型更改为“动态库(.dll)”。
    PS:想输出静态库时选择“静态库(.lib)”
    004-配置项目属性为动态库

    3、为项目添加CUDA配置

    如果项目未用到CUDA,可以跳过这一步。
    选中TestMakeLib,右键菜单—>生成依赖项—>生成自定义。
    005-配置CUDA
    选择CUDA(安装环境时需要先安装VS2022再安装CUDA,否则可能没有这个选项)
    006-配置CUDA

    4、添加相关代码文件到工程

    把动态库相关的代码添加到项目中。
    个人喜欢把代码按照一定的文件夹结构,复制到工程目录。
    然后在工程中创建与文件夹结构相同的筛选器,
    最后通过“添加–现有项”把代码文件加入到对应的筛选器中,删除工程自动生成的其他筛选器。
    最终如下图:
    007-添加相关代码文件到工程
    保险起见,针对.cu后缀的CUDA代码需要确认一下其配置属性是否正确。
    选中.cu文件,右键菜单—>属性,弹出如下文件属性页,
    如果环境配置正确的话,“常规—>项类型”会默认为“CUDA C/C++”
    如果不是且无法更改成“CUDA C/C++”,需要确认第三步和VS、CUDA环境是否安装、配置正确。
    008-CUDA文件确认

    5、修改头文件函数声明

    这里我们按最简单的来。
    在头文件的函数声明前,添加__declspec (dllexport)
    仅需要在对外提供的函数前添加,不打算开放的不用添加。

    __declspec (dllexport) double cpuSecond();
    __declspec (dllexport) void showTimeSpend(double start, const char* flag);
    
    • 1
    • 2

    009-修改头文件函数声明

    6、编译

    编译后出现下面的提示表示lib库编译成功了。
    010-lib生成成功
    因为我们一直是Debug模式,在Debug目录中可以找到生成的lib和dll文件
    011-lib生成成功

    二、VS加载动态库

    接下来在其他VS工程中引用刚生成的动态库。
    主要有两种方式:

    1、通过属性页配置(适用于普通VS工程)

    ①通过VS2022创建一个“控制台应用”,如TestUseLib
    ②将上面生成的lib、dll文件拷贝到新工程中(目录结构:工程根目录\Lib)
    ③将用到的头文件拷贝到新工程中
    ④选中工程TestUseLib,鼠标右键菜单—>属性—>VC++目录,编辑
    PS:如果需要指定include目录的话,可以通过编辑下图中的“包含目录”来实现,这里就不演示了。
    012-编辑lib目录
    推荐使用相对目录,添加Lib库目录“工程根目录\Lib”
    013-编辑lib目录
    选择链接器—>输入—>附加依赖项,这里要指定具体的lib文件,推荐使用相对目录
    014-指定链接库
    ⑥最后,将dll文件拷贝到工程主目录或者exe文件所在的目录,即可正常使用。

    2、通过CMakeLists.txt配置(适用于VS CMake工程)

    其他细节不再描述了,贴一下配置好的CMakeLists.txt文件

    # 指定cmake最小版本
    cmake_minimum_required (VERSION 3.11)
    
    # 声明一个工程Test1,编码语言C++(工程名可以不使用双引号)
    project("Test1" LANGUAGES CXX)
    
    # 查找所有的Source文件,记入到自定义ALL_SRC表中
    file(GLOB_RECURSE ALL_SRC
    	#${PROJECT_SOURCE_DIR}/*.cpp
    	${PROJECT_SOURCE_DIR}/CMakeProject1.cpp
    	#${PROJECT_SOURCE_DIR}/Algorithm/*.c
    )
    
    # 输出日志,便于查看
    MESSAGE("*** add_executable:" ${ALL_SRC})
    MESSAGE("*** PROJECT_NAME:" ${PROJECT_NAME})
    
    # 添加一个可执行文件,源文件由ALL_SRC中记录的Source文件组成
    add_executable(${PROJECT_NAME} ${ALL_SRC})
    
    # 查找Lib文件
    file(GLOB_RECURSE ALL_LLB
    	${PROJECT_SOURCE_DIR}/Lib/*.lib
    )
    MESSAGE("*** target_link_libraries:" ${ALL_LLB})
    
    # 将库文件链接到可执行文件
    target_link_libraries (${PROJECT_NAME} ${ALL_LLB})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    三、QT(MinGW编译)加载MSVC动态库

    QT可以通过CMake构建也通过qmake构建。
    通过Cmake Build时,使用CMakeLists.txt配置,方法与VS的Cmake相同。
    这里主要记录一下qmake Build时如何加载动态库。

    方法1、在pro文件配置

    #$$PWD表示当前目录,这里就是pro文件所在目录
    #注意-L和-l,这里lib文件名称为TestMakeLib.lib
    LIBS += -L$$PWD/Lib/ -lTestMakeLib
    
    • 1
    • 2
    • 3

    方法2、工程右键菜单配置

    选中项目,右键菜单—>添加库…—>外部库—>下一步
    QT配置库
    按照提示选择库文件,其他默认即可。
    QT配置库
    最后,pro文件中会自动添加如下内容:

    win32:CONFIG(release, debug|release): LIBS += -L$$PWD/Lib/ -lTestMakeLib
    else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/Lib/ -lTestMakeLibd
    else:unix: LIBS += -L$$PWD/Lib/ -lTestMakeLib
    
    INCLUDEPATH += $$PWD/Lib
    DEPENDPATH += $$PWD/Lib
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    参考

    感谢以下作者的分享
    001-VS2019编译生成动态链接库dll的两种方式
    002-动态库关键字:__declspec(dllexport)和__declspec(dllimport)
    003-在VS2022 MFC程序中调用CUDA代码
    004-Visual Studio 2022使用MinGW来编译调试C/C++程序
    005-一文搞懂如何在CMake中使用Qt
    006-如何为Qt项目 添加第三方库头文件和lib 以及 解决中文乱码

    // 更优雅的设计,出自参考002
    // 编译动态库时,头文件需要定义OSG_LIBRARY宏
    // 编译静态库时,头文件需要定义OSG_LIBRARY_STATIC宏
    // 其他程序使用库时,头文件不需要定义任何宏,只在遍历名称前加OSG_EXPORT即可
    #  if defined( OSG_LIBRARY_STATIC )
    #    define OSG_EXPORT
    #  elif defined( OSG_LIBRARY )
    #    define OSG_EXPORT   __declspec(dllexport)
    #  else
    #    define OSG_EXPORT   __declspec(dllimport)
    #  endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    最近又遇到了C++类导出库的问题,有以下参考感觉挺不错的
    001-C++动态库导出类方法
    002-C++导出类示例
    003-C++ DLL导出类

  • 相关阅读:
    Docker镜像详解(手拉手教你上传至阿里云,发布到私有库)
    Vue3+node.js网易云音乐实战项目 歌单页面详细代码
    C++ 关于引用的思考
    贪心算法学习——最大数
    CORS(跨域资源共享)
    【Rust】操作日期与时间
    【ICer必备基础】MOS电容——电容电压特性详解
    Swift中的继承(Inheritance)
    【六祎 - Mac】Mac安装Nginx;Mac编译安装Nginx;
    SpringBoot - @JsonFormat注解详解
  • 原文地址:https://blog.csdn.net/cshoney/article/details/127656627