VS2019环境下C++动态链接库(DLL)的创建与调用

VS2019环境下C++动态链接库(DLL)的创建与调用本文旨在介绍如何在 VS2019 的环境下建立动态链接库以及如何调用动态链接库

欢迎阅读

你好! 这是我第一次写博文,有不足之处烦请指出。

声明

本文内容由作者查阅多方资料,亲自实验后总结得出!严禁任何形式的抄袭!请尊重作者!

一、实验环境

VS2019、Win10

二、创建动态链接库(DLL)

首先,我们需要知道动态链接库(以下简称DLL)的作用,我在这里总结为,可以重复使用功能相同的代码,而不必对已经实现了的功能重新编写代码。链接库有动态和静态两种,本文旨在记录如何实现DLL的创建与调用,故不对这两种链接库做探讨。接下来让我们开始实验吧

步骤<1>:创建新项目

创建新项目–>动态链接库(DLL)
第一张

步骤<2>:配置新项目

输入“项目名称”,然后选择工程“位置”,“解决方案名称”与“项目名称”相同,是自动生成的,如果没有特殊需求建议不要修改,不要勾选“将解决方案和项目放在同一目录中”,最后点击“创建”按钮。
第二张

步骤<3>:初始化界面

这是创建工程之后的初始化界面,其中的代码是自动生成的,我们不需要去修改!
在这里插入图片描述

步骤<4>:新建文件

接下来创建我们自己的DLL:
(1)首先新创建头文件“TestDLL.h”,它的作用是用来声明需要导出的函数接口。
在这里插入图片描述




(2)然后新创建源文件“TestDLL.cpp”,它的作用是用来实现被声明的函数。
在这里插入图片描述
此时工程目录结构如下图:
在这里插入图片描述
至此,所有的准备工作已完毕,接下来我们开始编写代码吧!








步骤<5>:代码编写

(1)首先我们要在‘TestDLL.h’中编写如下代码:

#pragma once #include  
     extern "C" __declspec(dllexport) void SayHello(); 

上面代码的功能是声明一个可被调用的函数“SayHello()”,它的返回类型是void。

现在分析一下extern "C" __declspec(dllexport) void SayHello();这一句代码,其中extern "C"的作用是告诉编译器将被它修饰的代码按C语言的方式进行编译,这么做的意义在此不做讨论,感兴趣的话可自行查询。
然后分析__declspec(dllexport),此修饰符告诉编译器和链接器被它修饰的函数或变量需要从DLL导出,以供其他应用程序使用;与其相对的还有一句代码是__declspec(dllimport),此修饰符的作用是告诉编译器和链接器被它修饰的函数或变量需要从DLL导入,它在后面也会被用到。
最后是函数void SayHello(),它就是需要被其他程序调用的函数。




效果图如下:
在这里插入图片描述

(2)然后我们需要在‘TestDLL.cpp’中实现在‘TestDLL.h’中被声明的SayHello()函数,代码如下:

#include "pch.h" #include "TestDLL.h" void SayHello() { 
    std::cout << "Hello!你成功了!" << std::endl; } 

效果图如下:
在这里插入图片描述

至此,DLL的代码编写完成。

步骤<6>:编译

最后一步是编译DLL:
单击
在这里插入图片描述





或者
按下’F5’




之后编译器会进行编译,成功之后会显示一个无法启动的错误,如下图:
在这里插入图片描述
不必担心,这是正常的现象,因为DLL不是可执行文件.exe,所以无法被启动,单击‘确定’即可。
如果出现的是其他错误,还需根据“错误列表”自行改正错误!






至此,DLL的创建全部完成!

此时在TestDLL的工程目录下的Debug文件夹中会出现如下图所示的5个文件:
在这里插入图片描述
其中“TestDLL.dll”和“TestDLL.lib”是我们等会儿会用到的文件。




三、调用动态链接库(DLL)

通过上面的步骤,我们现在已经创建好了可被调用的DLL了,接下来需要创建一个调用TestDLL的C++工程项目

步骤<1>:新建一个C++工程项目

此处创建C++工程项目的目的是为了测试刚刚写好的TestDLL库,所以和创建普通的C++工程项目一样没有什么区别,所以此处不再给出详细的创建过程。

下图显示的是我已经创建好了的名为“TestDLLCreated”的C++工程项目:
在这里插入图片描述

步骤<2>:为编写调用代码做准备

这一步需要做以下几件事:

1. 将TestDLL的工程目录下的Debug文件夹中的“TestDLL.dll”和“TestDLL.lib”文件复制到“TestDLLCreated”工程目录下的TestDLLCreated文件夹中。

注意:每个人的工程目录的路径可能不太一样,请大家因地制宜(此处用词不太准确,哈哈)!

在这里插入图片描述
复制到
在这里插入图片描述
2.将TestDLL的工程目录下的TestDLL文件夹中的“TestDLL.h”头文件复制到“TestDLLCreated”工程目录下的TestDLLCreated文件夹中






注意:每个人的工程目录的路径可能不太一样,请大家因地制宜(此处用词依然不太准确,哈哈)!


在这里插入图片描述
复制到
在这里插入图片描述
3.将刚刚添加到“TestDLLCreated”工程目录下的TestDLLCreated文件夹中的“TestDLL.h”头文件导入到VS中的解决方案资源管理器中。








在箭头所指处右键
在这里插入图片描述
然后选择“添加”–>“现有项”
在这里插入图片描述
选择“TestDLL.h”之后点击添加按钮:
在这里插入图片描述
添加完成之后:
在这里插入图片描述
至此,为编写调用代码所做的准备全部完成!
















步骤<3>:编写调用代码

1.首先修改“TestDLL.h”头文件中的代码:

//原来的代码 #pragma once #include  
     extern "C" __declspec(dllexport) void SayHello(); 

修改

//修改后的代码 #pragma once #pragma comment(lib,"TestDLL.lib") #include  
     extern "C" __declspec(dllimport) void SayHello(); 

在这里分析一下为什么要这样修改,首先是添加了一行代码:#pragma comment(lib,"TestDLL.lib"),它的作用是将“TestDLL.dll”链接到TestDLLCreated工程项目中;
然后将代码extern "C" __declspec(dllexport) void SayHello();修改为extern "C" __declspec(dllimport) void SayHello();,作用是告诉编译器和链接器被__declspec(dllimport)修饰的函数或变量需要从DLL导入,前面也有过介绍。

2.然后,修改TestDLLCreated.cpp源文件中的代码

//原来的代码 // // // TestDLLCreated.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include  
     int main() { 
    std::cout << "Hello World!\n"; } // 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单 // 调试程序: F5 或调试 >“开始调试”菜单 // 入门使用技巧:  // 1. 使用解决方案资源管理器窗口添加/管理文件 // 2. 使用团队资源管理器窗口连接到源代码管理 // 3. 使用输出窗口查看生成输出和其他消息 // 4. 使用错误列表窗口查看错误 // 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目 // 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件 

修改

//修改后的代码 // // // TestDLLCreated.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include "TestDLL.h" int main() { 
    SayHello(); } // 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单 // 调试程序: F5 或调试 >“开始调试”菜单 // 入门使用技巧:  // 1. 使用解决方案资源管理器窗口添加/管理文件 // 2. 使用团队资源管理器窗口连接到源代码管理 // 3. 使用输出窗口查看生成输出和其他消息 // 4. 使用错误列表窗口查看错误 // 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目 // 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件 

分析:在“TestDLLCreated.cpp”源文件中先include头文件“TestDLL.h”(去掉#include 是因为它在“TestDLL.h”已经被包含了),然后在main()函数中调用被导入的SayHello()函数。

至此,调用代码编写完成!

步骤<3>:编译代码

编译成功之后的结果如下:
在这里插入图片描述
成功调用,说明所有工作都已正确完成!




四、总结

1、上述教程只适用于调试模式下,若想直接启动TestDLLCreated.exe应用程序,还需将“TestDLL.dll”和“TestDLL.lib”文件复制到与TestDLLCreated.exe同一目录下才可以运行!
2、希望可以帮到大家。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/212466.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午7:59
下一篇 2026年3月18日 下午7:59


相关推荐

  • 简单详细的SpringBoot自动配置原理解析

    简单详细的SpringBoot自动配置原理解析SpringBoot启动会根据条件加载配置

    2022年6月16日
    32
  • linux vim用不了(排位老是遇到坑怎么办)

    这里写自定义目录标题Vim是Linux常用的文本编辑器新的改变插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML图表FLowchart流程图导出与导入导出导入Vim是Linux常用的文本编辑器1、 输入命令vi文件名,进…

    2022年4月11日
    33
  • redis启动停止,查看redis端口

    redis启动停止,查看redis端口查看所有 redis 进程 psaux grepredis 停止 rediskill 根据 pid 来暴力停止 redis 进程 这里我只停止了其中一个 redis 后台启动 redis 集群和 sentinel 并且指定配置文件启动 redis app01 gcdc wxtest01 cdredis bin app01 gcdc wxtest01bin

    2026年3月18日
    2
  • Java 日志相关的面试

    近期整理的关于日志的面试题,对于初级者来说,很少会涉及到日志的处理,架构的选择。但是我相信作为一个资深者,这部分是必不可少的,同时也是评定一个系统的指标,足以证明日志的重要性。1.常用的日志框架    JavaLoggingAPI(Oracle)——Java默认的日志框架    Log4j(Apache)——开源日志框架    Logback(LogbackProject)——开源项目,…

    2022年4月7日
    34
  • [NOIP2011真题]选择客栈[通俗易懂]

    [NOIP2011真题]选择客栈[通俗易懂]题目背景NOIP2011提高组DAY1试题。题目描述丽江河边有n家很有特色的客栈,客栈按照其位置顺序从1到n编号。每家客栈都按照某一种色调进行装饰(总共k种,用整数0~k-1表示),且每家客栈都设有一家咖啡店,每家咖啡店均有各自的最低消费。两位游客一起去丽江旅游,他们喜欢相同的色调,又想尝试两个不同的客栈,因此决定分别住在色调相同的两家客栈中。晚上,他们打算选择一

    2026年3月3日
    4
  • Idea激活码永久有效Idea2020.1.3激活码教程-持续更新,一步到位

    Idea激活码永久有效Idea2020.1.3激活码教程-持续更新,一步到位Idea激活码永久有效2020.1.3激活码教程-Windows版永久激活-持续更新,Idea激活码2020.1.3成功激活

    2022年6月17日
    282

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号