C/C++ 动态链接库(dll)的生成与调用

文档声明:
以下资料均属于本人在学习过程中产出的学习笔记,如果错误或者遗漏之处,请多多指正。并且该文档在后期会随着学习的深入不断补充完善。感谢各位的参考查看。


笔记资料仅供学习交流使用,转载请标明出处,谢谢配合。
如果存在相关知识点的遗漏,可以在评论区留言,看到后将在第一时间更新。
作者:Aliven888

1、开发环境

系统:win7 x64 旗舰版
编译器: Visual Studio 2015
编译环境:Debug x86

2、简介

  可以说,学习C/C++开发的人掌握动态链接库和静态链接库的制作与使用,可谓是最基本的技能了。

静态库和动态库:
静态库:包含函数代码本身,在编译时直接将代码加入程序当中,称为静态链接库static link library。函数和数据被编译进一个二进制文件(扩展名通常为.lib),在使用静态库的情况下,在编译链接可执行文件时,链接器从静态库中复制这些函数和数据,并把它们和应用程序的其他模块组合起来创建最终的可执行文件(.exe)。当发布产品时,只需要发布这个可执行文件,并不需要发布被使用的静态库。

动态库:包含了函数所在的DLL文件和文件中函数位置的信息(入口),代码由运行时加载在进程空间中的DLL提供,称为动态链接库dynamic link library。在使用动态库时,往往提供两个文件:一个引入库(.lib,非必须)和一个.dll文件。这里的引入库和静态库文件虽然扩展名都是.lib,但是有着本质上的区别,对于一个动态链接库来说,其引入库文件包含该动态库导出的函数和变量的符号名,而.dll文件包含该动态库实际的函数和数据。

本章节只会介绍动态链接库的制作与使用;其中需要注意的是,动态链接库的制作有 使用 __declspec(dllexport) 创建dll使用模块定义(.def)文件创建dll 两种方式,这里我们先重点介绍第一种,因为第一种方式使用起来更加的方便和灵活。

使用动态链接库的好处:

  • 可以使用多种编程语言编写:比如我们可以用VC++编写dll,然后在VB编写的程序中调用它。
  • 增强产品功能:可以通过开发新的dll取代产品原有的dll,达到增强产品性能的目的。比如我们看到很多产品改动了界面插件功能,允许用户动态地更换程序的界面,这就可以通过更换界面dll来实现。
  • 提供二次开发的平台:用户可以单独利用dll调用其中实现的功能,来完成其他应用,实现二次开发。
  • 节省内存:如果多个应用程序使用同一个dll,该dll的页面只需要存入内存一次,所有的应用程序都可以共享它的页面,从而节省内存。

3、相关知识介绍

在开始制作动态链接库之前,我们先了解一些与之有关的知识。

dllexport类: 声明类dllexport时,将导出其所有成员函数和静态数据成员。您必须在同一程序中提供所有此类成员的定义。否则,将生成链接器错误。此规则的一个例外适用于纯虚函数,您无需为其提供显式定义。但是,因为抽象类的析构函数总是由基类的析构函数调用,所以纯虚拟析构函数必须始终提供定义。请注意,这些规则对于不可导出的类是相同的。如果导出类类型的数据或返回类的函数,请确保导出该类。

dllimport类 声明类dllimport时,将导入其所有成员函数和静态数据成员。与dllimport和dllexport在非类类型上的行为不同,静态数据成员不能在定义dllimport类的同一程序中指定定义。

4、制作一个动态链接库

第一步:创建一个dll项目工程:
在这里插入图片描述

在这里插入图片描述

第二步:在项目工程中添加一个 .cpp 文件和 .h文件(名称可以根据自己的需求去定义)。

在这里插入图片描述

第三步:再两个文件中,分别写入如下代码:

//Alivendll.cpp
#include "Alivendll.h"

void AlivenTest()
{
	cout << "This is a dll test ." << endl;
}


//Alivendll.h
#pragma once
#include <iostream>
using namespace std;

#ifdef ALIVENDLL_EXPORTS  //该宏是项目自定义的
#define ALIVEN_API extern "C" __declspec(dllexport)
#else
#define ALIVEN_API extern "C" __declspec(dllimport)
#endif //ALIVENDLL_EXPORTS

ALIVEN_API void AlivenTest();


在这里插入图片描述

第四步:选择好编译环境后(这里我测试的环境的是 Debug x86),编译项目即可。最终我们可以获取到 Alivendll.dll 和 Alivendll.lib 文件。

在这里插入图片描述
在这里插入图片描述

5、使用动态链接库

第一步:创建一个项目工程,这里选择控制台应用程序。

在这里插入图片描述

在这里插入图片描述

调用动态链接库需要三个文件(.dll、.lib、*.h)如下图示;接下来我们详细讲解下调用过程:

在这里插入图片描述
第二步:将Alivendll.h放在应用程序的目录下(一般建议放到应用程序目录下,但是也可以放到其他目录下),并导入到应用程序中。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

第三步:将Alivendll.lib放在应用程序的目录下(一般建议放到应用程序目录下,但是也可以放到其他目录下),并导入到应用程序中。

这里需要注意下,Alivendll.lib 的导入有三种方式:
第一种:#pragma comment(lib, “Alivendll.lib”)
第二种:在属性中配置附加依赖项
第三种,直接加载到项目中。

详细操作可以参见《C/C++ 静态链接库(lib)的三种常用调用方式》这篇博客。

在这里插入图片描述
第四步:将Alivendll.dll放在应用程序的可执行文件(exe)目录下。

在这里插入图片描述

笔记跟新记录

时间内容
2020-11-04创建笔记
2020-11-08优化文章格式以及修改部分错别字
  • 2
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++中,我们可以使用动态链接库(Dynamic Link Library,DLL)来实现代码的重用和模块化。下面是一个简单的示例,展示如何使用Visual Studio创建一个可供其他程序调用DLL。 1. 创建一个新的DLL项目 在Visual Studio中,选择“文件”->“新建”->“项目”,在“Visual C++”类别下选择“Win32”,然后选择“Win32项目”。在“应用程序类型”中选择“DLL”,然后按照向导完成项目的创建。 2. 编写代码 在“Solution Explorer”窗口中,双击“dllmain.cpp”文件,这是DLL的入口点(相当于main函数)。在这个文件中,我们可以定义一些全局变量和函数,它们可以被导出到其他程序中使用。下面是一个简单的示例: ``` #include "stdafx.h" #include "dlltest.h" BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } int add(int a, int b) { return a + b; } ``` 在这个示例中,我们定义了一个add函数,它接受两个整数参数并返回它们的和。我们还需要将这个函数导出到其他程序中使用,这可以通过在函数声明前面添加__declspec(dllexport)来实现,如下所示: ``` __declspec(dllexport) int add(int a, int b); ``` 3. 编译DLL 按下F7键,或者选择“生成”->“生成解决方案”来编译DLL。编译成功后,在项目文件夹的“Debug”或“Release”文件夹下将生成一个DLL文件。 4. 使用DLL 要使用DLL,需要在其他程序中包含DLL的头文件,并将DLL文件放到与程序相同的目录下。在代码中,我们可以使用LoadLibrary函数加载DLL,然后使用GetProcAddress函数获取DLL中导出的函数地址,并调用它们。下面是一个示例: ``` #include <iostream> #include <Windows.h> #include "dlltest.h" int main() { HMODULE hDll = LoadLibrary(L"dlltest.dll"); if (hDll != NULL) { typedef int(*AddFunc)(int, int); AddFunc add = (AddFunc)GetProcAddress(hDll, "add"); if (add != NULL) { std::cout << add(1, 2) << std::endl; } FreeLibrary(hDll); } return 0; } ``` 在这个示例中,我们使用LoadLibrary函数加载了DLL,然后使用GetProcAddress函数获取了add函数的地址,并将其转换为函数指针类型AddFunc。最后,我们可以像调用普通函数一样调用这个函数。注意,在程序结束时,需要调用FreeLibrary函数释放DLL。 这就是一个简单的DLL编写和使用示例。当然,实际应用中可能需要更复杂的代码和数据结构来实现特定的功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值