dll动态链接库的简单使用

dll动态链接库简介

DLL(Dynamic Link Library)动态链接库是一种 Windows 程序库,其主要特点是动态加载和链接,使程序可以在运行时调用和卸载其中包含的函数或资源。DLL 动态链接库主要用于代码复用和资源共享。

与静态链接库不同,DLL 动态链接库并不在编译时链接到可执行文件中,而是在运行时由操作系统加载并链接到可执行文件中。这意味着可以在不停止程序运行的情况下更新 DLL 文件,从而实现程序的动态更新。此外,DLL 动态链接库的多个程序可以共享相同的 DLL(dll注入原理),从而减少了系统资源的消耗,提高了代码复用性。

通过导出函数,DLL 动态链接库可以暴露其功能并允许其他程序调用其中的函数。这使得 DLL 动态链接库非常适合实现公共功能。

创建项目

在vs中新建空项目,右键项目属性>配置属性>常规>配置类型>设置为.dll

设置生成dll

代码

#include <windows.h>
#include <iostream>

/*
	 __declspec(dllexport) 
	 在函数前加入表示该函数为导出函数
	
	extern "C"
	表示以c方式导出
 */
#define MY_API __declspec(dllexport)
extern "C" MY_API void hello(VOID);

// 导出函数实现
void hello(){
	std::cout << "hello dll" << std::endl;
}

/*
	DllMain 是 Windows DLL 动态链接库的入口函数,它会在 DLL 的加载、
	卸载、线程连接、线程断开等情况下被系统自动调用。
	在这些情况下,DllMain 函数可以执行一些初始化和清理操作,
	例如初始化全局变量、创建进程、加载其他 DLL 等。
*/
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;
}

DllMain函数相关

DllMain 是 Windows DLL 动态链接库的入口函数,它会在 DLL 的加载、卸载、线程连接、线程断开等情况下被系统自动调用。在这些情况下,DllMain 函数可以执行一些初始化和清理操作,例如初始化全局变量、创建进程、加载其他 DLL 等。

其中,参数 hinstDLL 表示 DLL 的实例句柄,参数 fdwReason 表示 DLL 被加载、卸载、线程连接、线程断开等情况,参数 lpvReserved 保留,一般为 NULL

以下是一些常见的使用场景:

当 DLL 被加载到内存时,fdwReason 为 DLL_PROCESS_ATTACH。在这种情况下,DllMain 函数可以执行一些初始化操作,例如为全局变量分配内存、创建线程、注册类等。

当 DLL 被卸载时,fdwReason 为 DLL_PROCESS_DETACH。在这种情况下,DllMain 函数可以执行一些清理操作,例如释放资源、关闭句柄等。

当线程连接到 DLL 时,fdwReason 为 DLL_THREAD_ATTACH。在这种情况下,DllMain 函数可以执行一些初始化操作,例如为线程分配内存、创建句柄等。

当线程从 DLL 中断开时,fdwReason 为 DLL_THREAD_DETACH。在这种情况下,DllMain 函数可以执行一些清理操作,例如释放资源、关闭句柄等。

需要注意的是,DllMain 函数的执行过程应该保持简单和快速,因为它在 DLL 的加载和卸载过程中会频繁调用,长时间的执行可能会影响系统性能。

注意:DllMain函数不是必须的,一些例子中,DLL并没有提供DllMain函数,应用工程也能成功引用DLL,这是因为Windows在找不到DllMain的时候,系统会从其它运行库中引入一个不做任何操作的缺省DllMain函数版本,并不意味着DLL可以放弃DllMain函数。


使用dll动态链接库

#include<Windows.h>
#include<iostream>

using namespace std;

// 声明函数指针和需要使用的函数一致
typedef VOID(*func)(void);

int main() {

	HINSTANCE hDll; //DLL句柄
	//加载dll注意这里需要填写正确的路径
	//加L转换为Unicode
	hDll = LoadLibrary(L"testDll.dll");

	if (hDll != NULL)
	{	
		// 从hDll句柄加载Dll中的方法
		func proc = (func)GetProcAddress(hDll, "hello");
		// 然后就可以像使用正常函数一样使用了
		proc();
	}
	return 0;
}


说在最后

安全申明:本人才疏学浅,若有任何谬误,欢迎指正

我的博客:ひかりの博客
csdn主页:csdn博客主页

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值