利用VS2019创建dll方法
动态链接库的定义及意义
动态链接库(Dynamic Link Library 或者 Dynamic-link Library,缩写为 DLL),是微软公司在微软Windows操作系统中,实现共享函数库概念的一种方式。
动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。函数的可执行代码位于一个 DLL 文件中,该 DLL 包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。DLL 还有助于共享数据和资源。多个应用程序可同时访问内存中单个 DLL 副本的内容。
如何在VS创建dll
首先在VS初始界面选择创建新项目,如图所示
选择动态链接库(DLL),选择好项目位置后点击创建。
入口函数DLLMain
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;
}
APIENTRY:__stdcall的宏定义, __stdcall是一种函数调用约定,被该关键字修饰的函数,其参数都是从右向左通过堆栈传递的 ,函数调用在返回前要由被调用者清理堆栈。
HMODULE:HMODULE表示模块句柄,在VS的速览定义中,我们可以查到HMODULE为HINSTANCE的宏定义,而HINSTANCE为void的宏定义。
DWORD:double word类型,为unsigned long宏定义,指明了调用原因。
LPVOID:void far宏定义,其中far指针的长度为32位,代表了该指针与其指向的数据段可能位于不同的段,使指针能够指向更大的内存范围。
DLL_PROCESS_ATTACH:当DLL被进程加载时DLLMain被调用
DLL_THREAD_ATTACH:当有线程被创建时DLLMain被调用
DLL_THREAD_DETACH:当有线程结束的时候DLLMain被调用
DLL_PROCESS_DETACH:当DLL被线程卸载的时候DLL被调用
如何创建导出函数
给函数加上__declspec(dllexport)修饰符,那么它就是一个导出函数了。
我们在项目中另创建一cpp文件,用于定义导出函数。
下面是导出函数的定义,由于我们希望编译器认识该函数为C语言函数,加上了extern "C"标志:
#include <stdio.h>
#include "pch.h"
extern "C" __declspec(dllexport) void fun() {
printf("dll function export sucessfully\n");
}
生成解决方案后,我们可以看到显示出这样一段话:
在项目的DEBUG文件夹下,我们可以看到生成的.dll文件
动态调用导出函数
动态调用DLL利用了LoadLibrary和GetProcAddress函数。
新建一个项目,将之前生成的dll文件放入该项目的目录下
#include <windows.h>
#include <tchar.h>
typedef void(*lpFun)(void);
int main() {
HINSTANCE hDLL;
lpFun fun;
hDLL = LoadLibrary(_T("Dll1.dll"));
if (hDLL != NULL)
{
fun = (lpFun)GetProcAddress(hDLL, "fun");
if(fun != NULL)
fun();
FreeLibrary(hDLL);
}
}
先通过LoadLibrary链接dll文件,再通过GetProcAddress函数获取dll中的函数,运行可以得到:
可见DLL函数被成功调用。