调用静态函数库(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替换即可,只要接口不变,就不需要改动使用动态库的程序
原文地址:https://www.cnblogs.com/Henry-ZHAO/p/12725201.html