非MFC的DLL -- 即使用 SDK API 进行编程,能被其他所有语言调用
目录
非MFC的DLL -- 即使用 SDK API 进行编程,能被其他所有语言调用
一、预备知识:
二、DLL函数导出与创建:
三、Dll文件的调用
一、预备知识:
1、动态库导出函数的查看:
使用Vc++自带的Depends工具进行查看,但是只能看到函数的名字,具体的函数参数及返回值看不到,所以要把动态库导出函数声明的头文件(.h文件)打包给<<开发者>> Depends工具自行下载。
2、DLL程序入口点函数:
CUI控制台程序(不是DOS):main
GUI用户界面程序:WinMain
DLL程序入口点函数:DllMain,注意:大小写是区别的(仅导出资源的DLL可以没有DllMain函数)。具体的参数的应用:
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
3、DLL导出方式:
(1)、增加def文件来导出
(2)、使用头文件,在文件中添加extern "C" declspec(dllexport)
4、DLL使用
当我们的程序需要使用DLL时,就需要去加载DLL,在程序中加载DLL有两种方法,分别为加载时动态链接(隐式链接)和运行时动态链接(显式链接)。
- 在加载时动态链接中,应用程序像调用本地函数一样对导出的DLL函数进行显示调用。要使用加载时动态链接,需要在编译和链接应用程序时提供头文件和导入库文件(.lib)。当这样做的时候,链接器将向系统提供加载DLL所需的信息,并在加载时解析导出的DLL函数的位置;(隐式链接)
- 在运行时动态链接中,应用程序调用LoadLibrary函数或LoadLibraryEx函数以在运行时加载DLL。成功加载DLL后,可以使用GetProcAddress函数获得要调用的导出的DLL函数的地址。在使用运行时动态链接时,不需要使用导入库文件。(显式链接),用完记得用FreeLibrary释放。
在实际编程时有两种使用DLL的方法,那么到底应该使用那一种呢?在实际开发时,是基于以下几点进行考虑的:
- 启动性能如果应用程序的初始启动性能很重要,则应使用运行时动态链接;
- 易用性在加载时动态链接中,导出的DLL函数类似于本地函数,我们可以方便地进行这些函数的调用;
- 应用程序逻辑在运行时动态链接中,应用程序可以分支,以便按照需要加载不同的模块.
二、DLL函数导出与创建:
(1)DLL 导出有两种方式
方式一:增加def文件导入方式:
1、打开VS2017---》文件----》新建----》项目,如下图:
2、在Dlltest.cpp中添加代码,添加一个函数。
3、写完代码之后,右键单击源文件---》添加---》新建项---》如下图:
4、在source.def文件中添加代码,如下图:
5、编译---》生成。打开debug目录,如下:
6、接下来看看我们的dll中安函数的导出情况,这里使用depends工具,将生成的Dll文件拖入depends工具,导入成功。如下图:
方式二:_declspec(dllexport) 导出方式:
1、在Dlltest.cpp文件中,增加一个函数,为dec。
2、选中头文件,右键单击头文件---》添加----》新建-----》头文件(Inc.h)。
3、在Dlltest中,将Inc.h在Dlltest.cpp头文件中包含.,点击重新生成。用dephends工具查看新生成的dll文件,成功导出,如下图:
至此,两种导出方式完成。add使用def来导出,dec使用_declspec(dllexport)导出。两种方式自己根据实际情况选择。
三、Dll文件的调用
目的:编写一个可行程序exe来调用Dll。
方式一:使用隐式链接方式:
1、打开vs 2017 ---->文件---》新建----》项目,如下图:
2、在头文件中添加Dlluser.h文件,添加导入代码,如下图:
3、在头文件中添加代码,调用dll中的函数。
4、将生成好的dll文件复制到Dlluser工程中的Debug目录,保证和生成的Dlluser.exe在同一目录。运行如下图,调用成功。
方式二:使用显示链接方式
1、添加调用 #include<Windows.h> 头文件。
2、定义函数指针地址 typedef int(*AddFunc)(int a, int b);
3、编写代码:
4、如下图:
5、调用结果显示,成功调用。