一、静态连接库:.LIB;
动态链接库:.DLL;
二、动态链接库的好处:
2.1、主要是代码的共享;
三、Win32 DLL 的创建和使用
文件->新建->工程:Win32 Dynamic-Link Library
PS:中间碰到一个很奇怪的问题,我新建一个cpp文件后,怎么编译在Debug文件夹下都没有dll文件,重新建立工程2次都没有。但是后来又成了。我估计是我的文件名称写错了,将cpp写成app了!浪费了一个半小时!!!!
3.1、从DLL中导出函数
a、在函数前面加"_declspec(dllexport)"。例如 _declspec(dllexport) int add(int a, int b){};
b、用命令dumpbin命令查看dll文件导出的函数。例如 dumpbin DLL1.dll;
四、隐式链接方式加载DLL
4.1、利用extern声明外部函数
例如:extern int add(int a, int b); 在这句代码的后面,EXE程序就可以调用add函数了。
4.2、dumpbin 命令不只可以查看dll的导出函数,也可以查看exe调用的函数。例如:dumpbin -imports DllTest.exe。可以查看EXE程序调用了哪些dll函数(即上面4.1提到的用extern声明的外部函数);
4.3、Depands工具
该工具是实现了dumpbin同样功能的一个可视化工具。用其打开一个EXE,可查看该EXE调用的DLL和该DLL的导出函数。如果用来查看DLL,可以查看该DLL导出的函数;
4.4、利用_declspec(dllimport)声明外部函数
用"_declspec(dllimport)"可以和“extern”实现同样的功能,例如:
_declspec(dllimport) int add(int a, int b);
但是,如果调用的是动态库的话,"_declspec(dllimport)"命令可以是"编译器"生成“效率更高”的代码。
Q:为什么"_declspec(dllimport)"会令编译器生成效率更高的代码呢?
A:暂时不知!
五、从DLL中导出C++类
5.1、导出C++类的方法
class _declspec(dllexport) 类名{};
5.2、导出C++类中的函数的方法
例如:
class /*DLL1_API*/ Point
{
public:
void DLL1_API output(int x, int y);
void test();
};
此段代码就是讲类Point中的output函数导出,而test函数没有导出。在用命令dumpbin -exports DLL文件名 查看时,发现只导出类output函数,没有导出Point类。
六、解决名字改编问题
6.1、利用限定符:extern “C" 可以解决C++和C语言之间相互调用时函数命名的问题。但是这种方法有一个缺陷,就是不能用于导出一个类的成员函数,只能导出全局函数这种情况;
PS:如果再DLL需要导出的函数前面加上extern ”C"那么,C++写的DLL就可以被C写的客户端调用;
6.2、DEF文件的方式,可以让_stdcall的函数名称不改变,并且可以设定函数名称。包括类函数的名称。但是能不能定义类的名称暂时不知道。
七、显示加载方式加载DLL
简单介绍:主要通过
HMODULE LoadLibrary(LPCTSTR lpFileName);
FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName);
两个函数来实现动态加载的。不需要在工程->设置->连接 里面设置lib。
静态加载在程序启动的时候就已经被加载到内存中了,而动态加载会在程序启动以后,调用时再加载到程序当中。节约内存,并且动态加载DLL的EXE,用工具或命令无法查看到相关调用信息。
7.1、根据函数名称动态加载DLL。函数名称,或者是名字改编的字符串(即用dumpbin -exports 命令查看的函数名称字符串);
72.、 也可以根绝序号调用DLL的函数,这样无论DLL的函数名称是否改编,只要知道需要可参数结构就可以调用。需要用到宏MAKEINTRESOURCE。例如:
MAKEINTSOURCE(1)表示需要为1的函数。
7.3、DllMain函数
7.4、MFC DLL
7.5、当动态加载链接库使用完毕后,最好能将DLL释放掉。用函数:
BOOL FreeLibrary(HMODULE hModule);
PS:有很多都很模糊,以后补充。