应用程序与dll的动态通信:c/c++

动态调用是在运行的时候完成的。

 

首先将指定模块加载到调用的进程的地址空间里

采用LoadLibraryA函数来处理来获取dll的句柄

https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibrarya

函数原型:

HMODULE LoadLibraryA( LPCSTR lpLibFileName );

参数

LPCSTR 是一个常量字符串相当于const char*

返回值

返回的是一个模块的句柄,可以通过该句柄来操作这个模块,如果返回值为NULL表示获取出错。

这里的HMODULE和HINSTANCE是同一个句柄,在vs2019的定义里面可以查到,而这两个句柄都表达一个意思就是载入模块的句柄,类似于这里的载入一个dll模块,或者是exe模块,只要是载入模块相关的都是这个句柄

处理:

 

 

从指定的dll中得到导出的函数或变量

采用GetProcAddress函数来处理:

https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getprocaddress

函数原型:

FARPROC GetProcAddress( HMODULE hModule, LPCSTR lpProcName );

参数

第一个参数表示的是HMODULE的一个句柄变量,第二个参数LPCSTR lpProcName表示的是一个需要的函数或变量的名字。

LPCSTR是一个常量字符指针等价于const char*

返回值

返回的是一个函数的调用地址,可以通过这个地址来调用或处理函数或变量。

这个GetProcAddress的返回值是一个FARPROC,通过vs2019查看得到的是Far WINAPI,这个有点涉及汇编的知识了,就是FAR这个关键字表示的是段跳转这个内存不够要用另外一个段而现在的机器都是64位了肯定是够的所以没啥用可以不用管,WINAPI就是一个函数约定。

 

处理:

由于这个返回值FARPROC现在是没啥用的,所以这里对于返回值直接强行转换就好了,然后由于返回的是一个函数的地址,所以需要用函数指针来处理,由于又需要强制转换所以又需要构造一个函数指针的结构体来处理。

 

 

 

调用

在程序编译后,将dll添加到执行程序的位置,就可以实现动态链接dll文件了。