02年世界杯韩国黑哨_曲棍球世界杯 - guanchafang.com

VS(visual studio) C++ 封装dll,以及其隐式调用与显式调用(静态\动态)
2025-07-09 20:20:10

DLL介绍

DLL(动态链接库,Dynamic Link Library)是一种可执行文件,它包含可以在其他程序中调用的函数和数据。他是Windows操作系统中的一个重要概念,用于代码共享和模块化。

特点

代码共享:多个程序可以同时使用同一个DLL文件,而不需要将其代码编译到每个程序中。这样可以节省磁盘空间和内存,并且可以简化程序的更新和维护。

运行时链接:与静态链接库(.lib文件)不同,DLL不是在编译时链接到程序中的,而是在程序运行时链接。这意味着,如果更新了DLL,使用该DLL的程序可以在不重新编译的情况下直接使用新版本。

多语言支持:DLL可以由不同的语言编写,例如C,C++,Delphi等,只要它们遵循一定的调用约定。

可拓展性:应用程序可以通过加载和卸载DLL来动态地增加或减少功能。

资源共享:DLL在内存中只有一个实例,所有使用它的应用程序都共享这个实例,从而节约了资源。

生成DLL

新建dll项目

新建项目-选择“win32控制台应用程序”

接着在弹出框中选择dll和空项目

完成后得到空项目的目录结构,创建DLL1.h和DLL1.cpp两个文件

书写代码

在DLL1.cpp中实现两个数求和与求差的接口:

int sum(int a, int b){

return a + b;

}

int sub(int a, int b){

return a - b;

}

在DLL1.h中声明函数:

int sum(int a, int b);

int sub(int a, int b);

为了能在dll中使用,还需要给函数加上前缀:extern "C" __declspec(dllexport)

其中_declspec(dllexport)的意思是指定需要导出到dll的目标(用于生成dll)

extern "C"表示将C语言程序导出为DLL

extern "C" __declspec(dllexport) int sum(int a, int b);

extern "C" __declspec(dllexport) int sub(int a, int b);

也可以使用宏定义,使代码更具可读性

#define SumAndSub_API __declspec(dllexport)

extern "C" SumAndSub_API int sum(int a, int b);

extern "C" SumAndSub_API int sub(int a, int b);

生成DLL

在.h和.cpp中添加代码之后,右击项目选择“生成”

生成成功后,在项目Debug文件夹下即可找到生成的dll文件

.h所在目录也需要记录一下

到这DLL的封装算是完成了

调用DLL

隐式调用

首先需要重新创建一个空项目来调用测试:

创建完成之后,还需引入三个文件即前面生成的DLL1.dll和DLL1.lib以及项目DLL1.h文件

其中DLL1.dll需要放在当前项目的Debug目录下,其他两个在属性中配置路径即可(DLL1.lib还需添加依赖项)

右击项目-选择属性

选择VC++目录

其中“包含目录” 添加.h文件所在文件夹

“库目录”添加.lib所在目录

添加完成后如图:

然后在链接器-输入选项中添加依赖项

完成后应用属性保存,然后将DLL文件复制到当前项目的Debug目录下

下面新建一个test.cpp来测试下是否能够成功调用到DLL

#include "iostream"

#include "DLL1.h"

using namespace std;

int main(){

cout << sum(2, 5) << endl;

cout << sub(5, 2) << endl;

system("pause");

return 0;

}

成功调用到DLL

显式调用

显式调用中又包含静态调用与动态调用。

静态显式调用

静态调用:.lib文件包含了函数代码本身,在编译时直接将代码加入程序当中,称为静态链接库(static link library)。静态调用使用静态链接库,链接器从静态链接库LIB获取所有被引用函数,并将库同代码一起放到可执行文件中。

先创建一个新的空项目,创建完成后添加一个.cpp源文件并写入简单的主函数

int main(){

}

右击项目选择-生成(生成Debug目录)

把DLL1.dll放到当前项目的Debug目录下

创建.cpp源文件通过以下代码进行静态调用

#include "iostream"

using namespace std;

#pragma comment(lib, "D:\\Code\\C++\\dll\\DLL1\\Debug\\DLL1.lib")

// dll中封装的函数

extern "C" __declspec(dllimport) int sum(int, int);

extern "C" __declspec(dllimport) int sub(int, int);

int main(){

cout << sum(2, 5) << endl;

cout << sub(5, 2) << endl;

system("pause");

return 0;

}

其中#pragma comment(lib, "D:\\Code\\C++\\dll\\DLL1\\Debug\\DLL1.lib")

表示链接DLL1.lib这个库,与在项目属性中的“VC++目录”中的“库目录”添加目录以及链接器-输入添加依赖性操作是等价的(一个显式一个隐式的区别)。

动态显式调用

动态调用:.dll文件包含了函数所在的DLL文件和文件中函数位置的信息(入口),代码由运行时加载在进程空间中的DLL提供,称为动态链接库(dynamic link library)。动态调用使用动态链接库,可执行模块(.dll文件或.exe文件)本身不包含它调用的DLL函数的代码,仅包含在运行时定位DLL函数的代码所需的信息,在程序运行时能够找到并链接到正确的DLL文件和函数。(这些信息通常包括函数名、参数类型等,足以让操作系统在运行时解析并调用正确的函数。)

同样创建项目后先生成Debug目录

生成之后将DLL1.dll放入Debug目录中

通过如下方式进行动态调用

首先通过LoadLibrary()函数来载入指定的dll文件,加载到程序的内存中(DLL没有自己的内存)

GetProcAddress()函数检索指定dll文件输出库函数地址,通过函数指针typedef int(*func)(int a, int b);来装载函数并使用。

FreeLibrary()释放dll所占的空间。

#include "iostream"

#include "windows.h"

using namespace std;

typedef int(*func)(int a, int b);

int main(){

// 动态加载dll

HMODULE hModule = LoadLibrary("DLL1.dll");

if (!hModule){

cout << "Error!" << endl;

}

// 装载函数

func sum = func(GetProcAddress(hModule, "sum"));

func sub = func(GetProcAddress(hModule, "sub"));

if (sum != NULL){

cout << sum(5, 2) << endl;

}

if (sub != NULL){

cout << sub(5, 2) << endl;

}

// 释放

FreeLibrary(hModule);

system("pause");

return 0;

}

加载dll的LoadLibrary()函数同样可以使用绝对路径,就无需将dll文件放到Debug目录下了

// 动态加载dll

HMODULE hModule = LoadLibrary("D:\\Code\\C++\\dll\\DLL1\\Debug\\DLL1.dll");

注意:动态调用方式通常是只有.dll文件,而缺少.h和.lib文件时使用,当三个文件都齐全时,应采用更加简单方便的隐式调用。

OPPOR11和华为nova2哪个自拍功能好?华为nova2与OPPOR11拍照对比样张评测
新iPad发布,苹果iPhone/iPad告别64GB时代
最新文章
  • 令我自豪的一件事作文 篇46相关推荐 令我自豪的一件事作文范文(精选46篇) 在学习、工作乃至生活中,大家或多或少都会接触过作文吧,作文可分为小学作文、中学作文...
  • 暗黑破坏神4做主线要花费多少时间-暗黑破坏神4主线时长介绍t2627_2_2627_1:5.0 t1-t0:33.0 t2-t1:7.0 t3-t2:0.0 t4-t3:3.0 t5-t4:11.0 t6-t5:19.0 t7-t6:3.0 t8-t7:0.0 t9-t8:11.0 t10-t9:0.0 t11-t10:4.0 t12-t11:0.0 t13-t12:0.0 t14-t13:0.0 t15-t14:0.0 t16-t1...
  • 《碧蓝航线》厌战改怎么样 厌战改属性技能效果一览t2627_2_2627_1:5.0 t1-t0:29.0 t2-t1:8.0 t3-t2:0.0 t4-t3:2.0 t5-t4:16.0 t6-t5:30.0 t7-t6:4.0 t8-t7:0.0 t9-t8:12.0 t10-t9:0.0 t11-t10:66.0 t12-t11:0.0 t13-t12:0.0 t14-t13:0.0 t15-t14:0.0 t16-t...
  • 伟大思想理论因何伟大伟大思想理论因何伟大 ——论习近平新时代中国特色社会主义思想的重大意义 何毅亭来源: 光明日报 中国特色社会主义进入了新时代。这是一...
  • 相机快门 deepseek相机快门速度(Shutter Speed)是指相机快门打开和关闭的时间长度,即光线进入相机传感器的时间。它是摄影中控制曝光的三大要素之一(另外两...
  • 追随者选择哪种最好?yjttt yjttt 当前离线 积分2240 威望14 魅力12 经验1568 热心度0 注册时间2010-12-30 最后登录2025-6-11 主题26 回帖290 精华0 阅读权限40 透视大地 透视大气 T...
  • 电脑键盘恢复键是哪个(键盘上的恢复键)请问电脑键盘中的复位键是哪一个键? 键盘上的R字母键也叫复位键。在游戏中按下去会回到固定的地图某处。台式机机箱上的复位键就是“RESET...
  • 萬古仙穹 (2017) Full online with English subtitle for free – iQIYI萬古仙穹details | 萬古仙穹Original9.0TV-PG2017Chinese MainlandMandarinFantasyVitality-themedAdventureReserveDescription: 一枚圍棋棋子,將本是生活在21世紀的商界精...
  • 理光SP 211驱动软件标签:理光打印机驱动 理光SP 211驱动是理光官方推出的一款适用于同型号打印机的驱动程序,如果你在使用这款打印机的时候出现了无法识...
  • 美剧巴士为什么看不了? 原因和解决方法分享!最近老剧荒,就想着找个地方补补老剧。朋友推荐个叫“美剧巴士”的,说是资源挺全。我这人就爱折腾,这就上手试试。 摸索过程 一开始还...