调用静态函数库(lib)和动态函数库(dll)
1.什么是静态链接库
静态库(Static Library)通常包含一堆程序员自定义的变量与函数,在编译期间由编译器和链接器将它集成到可执行文件中,也就是生成的.exe文件中
2.静态库的扩展名
在Windows下,静态库的扩展名是.lib,在Linux下是.a
3.静态库的优缺点
1)优点:
发布时只需发布.exe文件,因为库已经集成到可执行文件中,运行时不再依赖库
2)缺点:
静态库集成到.exe文件中,导致.exe文件较大,同时,如果后续想要升级库必须重新编译.exe文件。
生成静态库的过程源码中可以没有main()函数的,调用时只需要链接这个lib库即可,完成lib内部
函数的调用。
2.动态链接库:
可以生成动态链接库供外部(如exe)调用。
生成时,源码内需要在你允许对方显示调用的函数的定义前加上前缀__delsec(dllexport)。这样便会输出,.dll和.lib。
1 #include "func.h" 2 #include "stdafx.h" 3 4 extern "C" _declspec(dllexport) int SquareSum(int a, int b) 5 { 6 return (a*a + b * b); 7 } 8 9 extern "C" _declspec(dllexport) int SumSquare(int a, int b) 10 { 11 return ((a + b)*(a*b)); 12 }
然后调用的时候又有两种方式,显示调用和隐式调用。
显式调用:达到和函数定义在本文件中的效果一样,不需任何变化。(一般还是显示调用更普遍)
- 将.lib添加到工程的附加依赖,然后将dll拷到exe文件附近,先用extern __delsec(dllimport)声明我要从外部导入这个函数。就可以任意调用其中的函数了。lib中记录了函数在dll内的位置
1 #include <iostream> 2 using namespace std; 3 #include "func.h" 4 5 #pragma comment(lib,"DynamicLib32.lib") 6 7 int main() 8 { 9 int a = 34; 10 int b = 32; 11 cout << SquareSum(a, b) << endl; 12 cout << SumSquare(a, b) << endl; 13 14 system("pause"); 15 return 0; 16 }
还需要给调用添加声明此为外部调用的函数的头文件。
#pragma once//调用时要给编译器声明这是调用的外部函数 extern "C" _declspec(dllimport) int SquareSum(int a, int b); extern "C" _declspec(dllimport) int SumSquare(int a, int b);
隐式调用:通过包含window.h,用系统来调用。先声明指针,然后指针通过系统API去dll内部去找这个函数。
1 { 2 HINSTANCE hDllInst = LoadLibrary( "youApp.DLL "); 3 if(hDllInst) 4 { 5 typedef DWORD (WINAPI *MYFUNC)(DWORD,DWORD); 6 MYFUNC youFuntionNameAlias = NULL; // youFuntionNameAlias 函数别名 7 youFuntionNameAlias = (MYFUNC)GetProcAddress 8 (hDllInst, "youFuntionName "); 9 // youFuntionName 在DLL中声明的函数名 10 if(youFuntionNameAlias) 11 { 12 youFuntionNameAlias(param1,param2); 13 } 14 FreeLibrary(hDllInst); 15 } 16 }
3.为何多用显式调用的动态库?
- 静态库打包很大;然后如果库改变了,那使用库的程序需要重新编译,因为这个库已经融进程序中了。
- 动态库很小,同时多出调用一个函数,可共享只会加载一个;如果库改变了,只需要了用新的dll替换即可,只要接口不变,就不需要改动使用动态库的程序