[C++]C++动态链接库DLL的创建和调用

本文介绍了库在编程中的作用,区分了静态库和动态库(包括DLL)的概念,详细说明了它们的链接过程、优缺点,并演示了如何在VisualStudio中创建和调用动态链接库。
摘要由CSDN通过智能技术生成

一、什么是库

我们在编写C/C++等语言程序的时候,经常会遇到很多反复使用的或者常用的部分,如果没次都重新编写代码是一件十分麻烦且无意义的事情,会严重影响我们的工作效率以及代码的可读性,并且无法在其他项目重复使用我们的代码。因此我们可以将函数代码封装成一个库文件,方便其他项目的调用。

二、动态库和静态库

静态库和动态库从字面意思来看,区别就是静态和动态。而这里的静态和动态指的是库的链接阶段。可以看如下的编译过程。

静态库:在链接阶段库将会与目标汇编后的目标文件.o一起打包生成可执行文件。成为可执行文件的一部分,后续此库就可以消失了。也就是说在编译的最后一步(链接阶段),如果程序需要使用静态库,在这一步都会一起打包到可执行文件中。

优点:

1、 使可执行文件依赖项少,已经被打包到可执行文件中了

2、 编译阶段完成链接,执行期间代码装载速度快

缺点:

1、使可执行文件变大

2、若作为其他库的依赖库,将会造成多余的副本,因为必须与目标文件打包

3、升级不方便,升级必须重新编译

动态库:而动态库在编译阶段都不会有什么动作,只有在程序运行时才被加载,也就是动态库的链接是发生在程序运行时期的,它和可执行文件是分开的,只是可执行文件在运行的某个时期调用了它。

优点:

1、动态库可以实现进程之间资源共享,有一份就行。

2、升级程序简单,不需要重新编译。

缺点:

1、运行期间在加载,将会减慢代码执行速度。

2、增加程序的依赖项,必须跟着可执行文件一起。

三、动态链接库(DLL)的创建

1>>打开Visual Studio选择创建新项选择动态链接库(DLL),点击下一步

2>>配置项目名称点击创建

3>>分别创建用于声明和定义函数的头文件.h和源文件.cpp

4>>在头文件中定义我们的函数

指定符号的导入导出:

MSVC编译器提供了一系列C/C++的扩展来指定符号的导入导出,即__declspec属性关键字。

__declspec(dllexport) 表示该符号是从本DLL导出的符号。

__declspec(dllimport) 表示该符号是从别的DLL中导入的。

因此我们可以用一个一个宏来定义我们的导出导入关键字,如果定义了宏就设置了__declspec(dllexport)修饰符,若未定义则设置__declspec(dllimport)。

现在我们头文件中一个用于加法和减法的函数并加上宏定义的修饰符,以及声明一个需要导出的类的函数。

在我们创建的.cpp文件中包含我们的.h头文件并且实现我们的函数

5>>生成解决方案

声明并且实现完我们的代码后,点击生成解决方案

在我们的Debug目录下可以看到我们生成的dll文件以及一个lib文件。

到现在我们的动态库就创建完成了,接下来就是在一个新项目中调用我们的动态库了。

四、动态链接库(DLL)的调用

加载动态库有两种方式,分为隐式加载和显示加载。

隐式加载:所需文件:接口.h头文件,dll文件,lib文件。.h和.lib加载方式与静态加载完全一致。但.dll文件必须放在环境变量指定的目下。当然通常是与目标.exe文件放在一起。

显式加载:所需文件:dll文件。利用LoadLibrary()函数进行加载。

下面介绍一下常用的隐式加载的方法。

1>>首先创建一个用于测试的空项目

2>>隐式链接采用静态加载的方式,需要将创建的.dll文件以及.lib文件还有定义的.h头文件,拷贝至我们需要测试的新项目的目录下。

3>>将拷贝的头文件添加到空白项目中

4>>在属性—链接器—输入—附加依赖项中添加我们拷贝过来的.lib文件

5>>创建一个.cpp源文件开始进行我们动态库的调用,包含头文件后直接可以调用我们封装的函数

6>>查看调用后的结果

到现在已经成功的创建了我们的动态链接库dll,并且调用成功!

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
动态链接库是一种可重定位的二进制文件,它包含了一些可供其他程序调用的函数或数据。在 Windows 平台上,动态链接库采用 .dll 后缀名,而在 Linux 平台上则采用 .so 后缀名。在本文中,我们将介绍如何使用 MFC 调用 C 语言编写的动态链接库。 # 创建动态链接库 在 Windows 平台上,可以使用 Visual Studio 创建动态链接库。下面是一个简单的示例: ```c // mydll.h #ifndef MYDLL_H #define MYDLL_H #ifdef __cplusplus extern "C" { #endif __declspec(dllexport) int add(int a, int b); #ifdef __cplusplus } #endif #endif // MYDLL_H // mydll.c #include "mydll.h" int add(int a, int b) { return a + b; } ``` 这个动态链接库包含一个 add 函数,可以对两个整数求和。 # 调用动态链接库 在 MFC 项目中调用动态链接库,需要进行以下几个步骤: 1. 定义一个函数指针类型,指向动态链接库中的函数。 ```c++ typedef int (*AddFunc)(int, int); ``` 2. 加载动态链接库。 ```c++ HINSTANCE hinstLib = LoadLibrary(TEXT("mydll.dll")); if (hinstLib == NULL) { AfxMessageBox(TEXT("Failed to load library.")); return; } ``` 3. 获取动态链接库中的函数地址。 ```c++ AddFunc addFunc = (AddFunc)GetProcAddress(hinstLib, "add"); if (addFunc == NULL) { AfxMessageBox(TEXT("Failed to get function address.")); FreeLibrary(hinstLib); return; } ``` 4. 调用动态链接库中的函数。 ```c++ int result = addFunc(1, 2); CString str; str.Format(TEXT("1 + 2 = %d"), result); AfxMessageBox(str); ``` 5. 卸载动态链接库。 ```c++ FreeLibrary(hinstLib); ``` 完整的 MFC 代码示例: ```c++ typedef int (*AddFunc)(int, int); void CMyDlg::OnButton1() { HINSTANCE hinstLib = LoadLibrary(TEXT("mydll.dll")); if (hinstLib == NULL) { AfxMessageBox(TEXT("Failed to load library.")); return; } AddFunc addFunc = (AddFunc)GetProcAddress(hinstLib, "add"); if (addFunc == NULL) { AfxMessageBox(TEXT("Failed to get function address.")); FreeLibrary(hinstLib); return; } int result = addFunc(1, 2); CString str; str.Format(TEXT("1 + 2 = %d"), result); AfxMessageBox(str); FreeLibrary(hinstLib); } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FL1768317420

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值