• 静态库动态库链接分析


    本文为验证后的结果,准确性较高,适合任何人阅读

    静态库和动态库链接分析

    1、文件组成结构

    静态库:lib   头文件

    动态库:lib   dll  头文件

    从组成上看,动态库和静态库的差异在于动态库多了一份dll文件,导致动态库可以独立存在,

    2、链接方式

    静态库:只能静态链接

    动态库:动态链接和静态链接

    3、运行效果

    静态库:相当于直接把代码段写入到exe或dll文件中

    动态库:相当于与exe或dll形成了一种关系,exe或dll可以到动态库中去查找所需要的函数

     

    4、差别:

    静态库:不需要导出就可以被链接使用

    动态库:需要导出后方可使用(动态链接)

     

    5、编译

    静态库:编译后只有lib文件

    动态库:若没有导出函数刚只能编译出dll文件而没有lib因此无法静态链接

     

    6、导出类的链接

    静态库:不需要导出,可以直接链接

    动态库:必需要导出才可以链接,必须将类中所有函数导出才可以使用(对于public)

    对于(protected)无论导出或者不导出均无法直接使用

    对于(private)无论导出或者不导出均无法直接使用

     

    7、导出子类

    静态库:不需要导出,直接使用文件头就可以使用

    动态库:必须导出子类,

     若仅使用到子类函数,可以不用导出父类。

    若需要使用到父类中继承的函数时,需要将父类中相应的函数导出,否则无法使用

    私有函数成员无法在外部使用

    若类不导出,只导出成员函数,同样可以正常使用,

     

    小结,对于需要导出类时,建议使用静态库的方式,这样代码可以直接使用。

     

    8、对于编译链接

    静态库和动态库相同,若库中引用了很多外部库,且放在预编译头文件中,那么,在链接时可能无法找到某些库,此时需要在专用的导入库中增加,否则将链接失败,

    例如:在stdafx.h中加入了#include<vector>using std::vector;

    在链接时将无法使用,因此需要增加专用的头文件,以便可以正常链接。

     

    9、存在这样一种情况,在动态库中,若使用def文件将类导出,在引用时还需要增加__declspec(dllimport)吗?

     

    1. #pragma once  
    2. #ifdef _DLL_EXPLORT_  
    3.   
    4. #define DLLEXPLORT _declspec(dllexport)  
    5. #else  
    6.   
    7. #define DLLEXPLORT _declspec(dllimport)  
    8.   
    9. #endif  
    10.   
    11. DLLEXPLORT class  CTest1  
    12. {  
    13. public:  
    14.     DLLEXPLORT void A(void);  
    15.     DLLEXPLORT CTest1(void);  
    16. public:  
    17.     DLLEXPLORT ~CTest1(void);  
    18. protected:  
    19.     void B(void);  
    20. private:  
    21.     void C(void);  
    22. };  
    1. #include "StdAfx.h"  
    2. #include "Test1.h"  
    3.   
    4. DLLEXPLORT CTest1::CTest1(void)  
    5. {  
    6. }  
    7.   
    8. DLLEXPLORT CTest1::~CTest1(void)  
    9. {  
    10. }  
    11. DLLEXPLORT void CTest1::A()  
    12. {  
    13.     MessageBox(NULL,"ss","ss",MB_OK);  
    14.     B();  
    15.     C();  
    16. }  
    17.   
    18. _declspec(dllexportvoid A()  
    19. {  
    20.     MessageBox(NULL,"aa","aa",MB_OK);  
    21. }  
    22. void CTest1::B(void)  
    23. {  
    24.     MessageBox(NULL,"bb","bb",MB_OK);  
    25. }  
    26. void  CTest1::C(void)  
    27. {  
    28.     MessageBox(NULL,"cc","cc",MB_OK);  
    29.   
    30. }  
    1. #pragma comment(lib,"Linklib.lib")  
    2. #include "../../Linklib/Linklib/Test1.h"  
    1. CTest1 ss;  
    2.     ss.A();  



     

    小结:

    最终效果为程序均能够正常运行。

  • 相关阅读:
    31 整数中1出现的次数(从1到n整数中1出现的次数)
    算法寒假实习面试经过之 十一贝(offer) 联想研究院(电话一面 被拒)
    百度feed 寒假实习 一面二面(offer)
    30连续子数组的最大和
    29最小的K个数
    28数组中出现次数超过一半的数字
    MySQL操作数据库和表的基本语句(DDL)
    Oracle————存储过程与函数
    Oracle清空数据库中数据表数据的方法
    Linux之常用Shell脚本总结
  • 原文地址:https://www.cnblogs.com/lidabo/p/3553355.html
Copyright © 2020-2023  润新知