当前位置: 首页 > news >正文

动态链接库

动态链接库

动态链接库的概述

DLL就是真个windows操作系统的基础。动态链接库不能直接运行,也不能接收消息。他们是一些独立的文件

  • Windows API中的所有函数都包含在DLL中

  • 其中最重要的DLL

    • Kernel32.dll,它包含用于管理内存、进程和线程的各个函数:CreateThread
    • User32.dll,它包含用于执行用户界面任务(如窗口的创建和消息的传送)的各个函数
    • GDI32.dll,它包含用于画图和显示文本的各个函数。
    • Windbg 是个APP
  • 静态库和动态库

    • 静态库:函数和数据被编译进一个二进制文件(通常扩展名为**.LIB**)。在使用静态库的情况下,在编译链接可执行文件时,链接器从库中复制这些函数和数据并把他们和应用程序的其他模块组合起来创建最终的可执行文件(.EXE文件)
    • 在使用动态库的时候,往往提供两个文件:一个因入库和一个DLL因入库包含被DLL导出的函数和变量的符号名DLL包含实际的函数和数据。在编译链接可执行文件时,只需要链接引入库DLL中的函数代码和数据并不复制到可执行文件中,在运行时候,再去加载DLL,访问DLL中导出的函数
  • 使用动态链接库的好处

    1. 增强产品的功能。(更换界面的DLL)换皮肤

    2. 提供二次开发的平台。(SDK基础版本)

    3. 简化项目管理(串行开发,以多个DLL的方式实现)

    4. 可以节省磁盘空间和内存

    5. 有助于资源的共享。(对话框模板,字符串,图标)

    6. 有助于实现应用程序的本地化。(多语言版本)

    7. 可以采用多种编程语言来编写

      VB delphi写界面,然后调用MFC编写的DLL来完成业务开发

动态链接库的使用

DumpBin命令

建立DLL文件代码如下

Dll1.cpp

#include "pch.h"

// 当使用预编译的头时,需要使用此源文件,编译才能成功。

//提供给用户用的函数
//应用程序如果要访问某个Dll中的函数,那么函数必须是被已经导出的函数
//为了让DLL导出一些函数,需要在每一个将要被导出的函数前面添加
//标识符:_declspec(dllexport)  必须带,以生成.lib文件
_declspec(dllexport) int add(int a, int b)
{
	return a + b;
}

_declspec(dllexport) int substrcat(int a, int b)
{
	return a - b;
}

​ 如果要查出*.dll中包含信息,可在命令行下进入Debug所在目录,输入以下命令

dumpbin -exports dll.dll

有些时候由于某种安装原因,dumpbin被认为是无效命令,接下来在C:\Program Files\Microsoft Visual Studio\VC14\Bin\下找到VCVARS32.bat并在命令行运行,之后就能执行dumpbin命令了。

  • 名字改编 === 名字粉碎
  • exe运行的时候,系统将为exe分配一个4GB的地址空间,然后加载模块会分析该应用程序的输入信息,从中找到该程序将要访问的动态链接库信息。然后再用户机器上搜索这些动态链接库

MFC控件绑定

//用add和substract从外面导入的函数
//隐式链接 显示加载
extern int add(int a, int b);
extern int substrcat(int a, int b);
void CDllMFCTestDlg::OnBnClickedAddButton()
{
	// TODO: 在此添加控件通知处理程序代码
	CString str;
	str.Format(L"4 + 3 = %d", add(4, 3));
	MessageBox(str);
}

void CDllMFCTestDlg::OnBnClickedSubstractButton()
{
	// TODO: 在此添加控件通知处理程序代码
	CString str;
	str.Format(L"4 - 3 = %d", substrcat(4, 3));
	MessageBox(str);
}

为使编译器认识Add, Substract必须在之前使用两个声明:

extern int Add(int x,int y);

extern int Substract(int x,int y);


可以使用标识符表示这两个函数是从动态链接库的.lib文件引用的,以生成效率更高的代码


_declspec(dllimport) int Add(int x,int y);

_declspec(dllimport) int Subtract(int x,int y);

DLL的导入和导出以及条件编译

  • _declspec(dllexport)与_declspec(dllimport)与使用extern关键字这种方式对比,使用_declspec(dllimport)的标识符,他将告诉编译器是从动态链接库引入的

    • _declspec(dllexport)是 类、函数以及数据的声明的时候使用。把.dll里面的相关代码暴露出来给其他应用程序使用。**提供给别的应用程序使用。**标识提供者。供dll内部使用
    • _declspec(dllimport)是在外部程序需要使用DLL内相关内容使用的标识符。是把dll中的相关代码插入到应用程序中去。表示使用者,不是dll内部使用。
  • DLL实现之后,交给客户程序。Dumpbin

  • DLL的实现者和使用者不是同一个人。

    • 方案:dll + 头文件的方式
      • 头文件:建议使用条件指令编译。使得程序的可读性增强,灵活性增强。
  • 条件指令编译

    //如果定义了DLL1_API,则什么都不干,如果没有定义DLL1_API,则
    //DLL1_API _declspec(dllimport)
    //条件编译指令
    
    //#define DLL1_API _declspec(dllexport)
    
    #ifdef DLL1_API
    #else
    #define DLL1_API _declspec(dllimport)
    #endif // 
    
    
    DLL1_API int add(int a, int b);
    DLL1_API int substrcat(int a, int b);
    

从DLL中导出C++类

动态链接库导出整个类和仅导出该类的某些成员函数在实现方式的区别:

​ 如果在声明类时,制定了导出标志,那么该类中所有的函数都被导出;否则只有那些声明时指定了的导出标志的类成员函数才被导出

DLL1.cpp

void Point::output(int x, int y)
{
	//返回调用者进程当前使用的窗口
	HWND hWnd = GetForegroundWindow();
	//获取DC
	HDC hdc = GetDC(hWnd);
	char buf[32] = { 0 };
	sprintf_s(buf, "x = %d, y = %d", x, y);
	//输出坐标
	TextOutA(hdc, 0, 0, buf, strlen(buf));
	//释放DC
	ReleaseDC(hWnd,hdc);
}

void Point::test()
{
	int x = 1, y = 2;
	//返回调用者进程当前使用的窗口
	HWND hWnd = GetForegroundWindow();
	//获取DC
	HDC hdc = GetDC(hWnd);
	char buf[32] = { 0 };
	sprintf_s(buf, "x = %d, y = %d", x, y);
	//输出坐标
	TextOutA(hdc, 50, 50, buf, strlen(buf));
	//释放DC
	ReleaseDC(hWnd, hdc);
}

Dll1.h

//class DLL1_API Point
//{
//public:
//	void output(int x, int y);
//	void test();
//};
class  Point
{
public:
	void DLL1_API output(int x, int y);
	void test();
};

相关文章:

  • Pretraining Language Models with Text-Attributed Heterogeneous Graphs
  • Kubernetes控制平面组件:API Server Node 授权机制 详解
  • 刷题记录08
  • 16、Python面试题解析:python中的浅拷贝和深拷贝
  • 《Effective Objective-C》阅读笔记(上)
  • 电机控制的空间矢量调制 (SVPWM)
  • openharmony5.0中hdf框架中实现驱动程序的动态加载和管理的技术细节分析
  • C++中tuple的用法
  • Spring Boot 中的日志管理
  • 数据库设计的优化建议
  • AcWing 299 裁剪序列
  • 6种MySQL高可用方案对比分析
  • C语言基本知识------指针(4)
  • springboot004网页时装购物系统(源码+数据库+文档)
  • threejs 安装教程
  • 51单片机测试题AI作答测试(DeepSeek Kimi)
  • w~视觉~合集13
  • Sinusoidal、RoPE和可学习嵌入的详细介绍及它们增强位置感知能力的示例
  • 信而泰CCL仿真:解锁AI算力极限,智算中心网络性能跃升之道
  • 可视化报表
  • 种植耐旱作物、启动备用水源,甘肃各地多举措应对旱情
  • 回家了!子弹库帛书二、三卷将于7月首次面向公众展出
  • 外交部驻港公署正告美政客:威胁恫吓撼动不了中方维护国家安全的决心
  • 视频丨歼-10CE首次实战大放异彩
  • 湖南4个县市区被确定为野生蘑菇中毒高风险区:中毒尚无特效解毒药
  • 联合国:欢迎俄乌伊斯坦布尔会谈,希望实现全面停火