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);

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})

三、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

方法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

参考

感谢以下作者的分享
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

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

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐