Windows环境下动态库的加载有两种方式,记录如下。
环境:vs
1.加载动态库的两种方式
- 隐式加载
- 显式加载
2.隐式加载
隐式加载在程序开始执行时将dll文件加载到内存中。这种加载方式需要:.h文件,.dll文件,.lib文件。
在vs的项目属性->链接器的附加库目录设置为存放.lib文件的路径,附加依赖项加入用到的.lib文件名字。将.dll文件和项目生成的.exe文件放在一起就可以使用.dll文件中的函数了。
如果.lib文件没有放入搜索路径,可在程序中使用#pragma comment(lib,libpath)显示链接。
3.显式加载
显式加载是实时加载,程序需要时加载,不需要时卸载。这种加载方式需要:.h文件,.dll文件。
这种加载方式的示例参考在程序中动态加载动态库(win)。
下面说一下示例程序的.h文件:
(1)extern "C"
链接器生成的DLL文件中会嵌入一个导出符号表,这个导出段列出了导出的变量、函数和类的符号名。
C语言不支持重载,由C编译器编译的动态库导出的函数的符号名就是源代码中函数的名字。C++语言支持重载,由C++编译器编译的动态库导出的函数的符号名不是源代码中函数的名字,C++编译器会对源代码中函数的名字做一个修改,以确保导出的函数的符号名的全局唯一性。
使用extern "C"就是要告诉编译器不要对函数名就行修改,以C语言的方式导出函数的符号名。由C++编译器生成的函数的符号名需要使用工具才能查看,这样就不方便对库函数的调用,使用extern "C"来指定编译器生成C风格的函数符号,方便对库函数的调用。
(2)__declspec(dllexport)
编译器看到一个变量、函数或者C++类被它修饰,那么它就知道应该在生成的DLL 模块中导出该变量、函数或C++类。
(3)__declspec(dllimport)
编译器看到一个变量、函数或者C++类被它修饰,那么它就知道可执行文件或DLL的源文件需要从其它DLL模块中导入一些变量和函数。
注:
(1)dumpbin(vs自带):查看DLL库中函数的符号名。
(2)在一些对外提供接口的项目中,业务逻辑可以使用C++面向对象思想去完成,对外提供接口的方式可以按照示例程序在程序中动态加载动态库(win)中的方式对外提供。