演练和使用自己的动态链接库C++
1.在visual studio中创建DLL项目。
2.将导出的函数和变量添加到该DLL。
3.在Visual Studio 中创建一个控制台应用项目。
4.在该控制台应用中使用从DLL导入的函数和变量。
5.运行已完成的应用。
本演练中两个方案,一个生成 DLL,另一个生成客户端应用。 DLL 使用 C 调用约定。 只要平台、调用约定和链接约定匹配,便可从采用其他编程语言编写的应用中进行调用。 客户端应用使用隐式链接 ,其中 Windows 在加载时将应用链接到 DLL。 此链接允许应用调用 DLL 提供的函数,就像调用静态链接库中的函数一样。
创建DLL项目
新建一个MathLibrary.dll项目,可以搜索dll来创建,我这里的版本是visual studio 2022
创建以后就可以在解决方案资源管理器中看到生成的项目和源文件了
接下来我们需要创建一个头文件来声明DLL导出的函数,然后将函数定义添加到DLL,使之具备功能。
1.将头文件添加到DLL
1.在菜单栏中选择项目-添加新项
2.左侧选择Visual C++。选择头文件(.h)。指定MathLibrary.h作为头文件的名称。生成文件。
这里的实例是斐波那契递归
1 |
|
头文件中声明一些函数以生成通用的斐波那契序列,给定了两个初始值。
2.向DLL添加实现
1.在解决方案资源管理器中右键点击源文件-添加-新项,创建名为MathLibrary.cpp的新.cpp文件。
编辑该文件
1 |
|
到这里dll文件就编写完毕了,可以通过点击菜单栏中生成-生成解决方案来查看是否有错误。
这样就成功使用visual studio创建了一个dll。
创建可使用DLL客户端应用
使用visual studio新建一个控制台应用,将项目名称设置为MathClient。(不需要选中将解决方案和项目放在同意目录中)
在源代码中调用MathLibrary函数,项目中必须包括MathLibrary.h文件,将头文件复制到客户端应用项目中,然后将其作为现有项添加到项目中。
在你的默认目录下去找到MathLibrary.h的文件和framework.h的文件复制到MathClient/MathClient的目录下,再去MathLibrary的x64/debug目录下去找到.dll文件和.lib文件,一个是动态链接库,一个是静态链接库,同样复制到MathClient/MathClient的目录下。
完成上述以后,右击解决方案资源管理器中的MathClient,属性-常规-包含目录,添加MathClient/MathClient,这样就可以使用.dll库和头文件了。
然后在MathClient.cpp文件中写入以下代码:
1 | // Mathclient.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 |
如果头文件上的include没有下划报错什么的就是包含目录路径设置好了)
设置依赖和附加库目录
项目-属性-链接器,右侧框中有一个附加依赖项,输入MathLibrary.lib,添加依赖
项目-属性-链接器-常规, 右侧框中附加库目录,定位到dll文件的库中。
报错提醒)
折腾这个dll的链接其实还挺麻烦的,一开始怎么也弄不对,重新写了很多遍。最后卡在link2019的一个报错上。它提示我main函数中找不到__imp_xxxx(函数)。
这里我先使用dumpbin工具查看dll导出符号,因为是cpp文件,所以有符号被修饰的可能性,导出符号的方法看https://blog.csdn.net/zsc_976529378/article/details/105834611
因为我找到的dumpbin.exe不对劲,所以我是用第二种方法的,但找不到命令提示所以可以自己搭建一个。
1 | 从菜单选择“Tools”,然后选择“外部工具”。输入如下: |
然后就可以在菜单-工具中找到命令提示了)
查看dll导出符号没有被改,就转眼到了这个
1 | __imp_xxxx |
是个什么东西,经过google后发现需要将lib文件添加到代码工程中
原文链接:https://blog.csdn.net/HideInTime/article/details/103181629
1 | 出现字符_imp,说明不是真正的静态库,而是某个动态库的导入库,导入函数和自己不同名,所以加了字符_imp。比如说_imp_GetUserNameA就是GetUserNameA函数。 |
于是在控制台文件main函数开头加入一行
1 |
就可以成功运行了!
Author: John Doe
Link: http://example.com/2022/02/18/DLL/
Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.