靜態庫動態庫鏈接分析
本文為驗證后的結果,準確性較高,適合任何人閱讀
靜態庫和動態庫鏈接分析
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)嗎?
[cpp] view plaincopy
- #pragma once
- #ifdef _DLL_EXPLORT_
- #define DLLEXPLORT _declspec(dllexport)
- #else
- #define DLLEXPLORT _declspec(dllimport)
- #endif
- DLLEXPLORT class CTest1
- {
- public:
- DLLEXPLORT void A(void);
- DLLEXPLORT CTest1(void);
- public:
- DLLEXPLORT ~CTest1(void);
- protected:
- void B(void);
- private:
- void C(void);
- };
[cpp] view plaincopy
- #include "StdAfx.h"
- #include "Test1.h"
- DLLEXPLORT CTest1::CTest1(void)
- {
- }
- DLLEXPLORT CTest1::~CTest1(void)
- {
- }
- DLLEXPLORT void CTest1::A()
- {
- MessageBox(NULL,"ss","ss",MB_OK);
- B();
- C();
- }
- _declspec(dllexport) void A()
- {
- MessageBox(NULL,"aa","aa",MB_OK);
- }
- void CTest1::B(void)
- {
- MessageBox(NULL,"bb","bb",MB_OK);
- }
- void CTest1::C(void)
- {
- MessageBox(NULL,"cc","cc",MB_OK);
- }
[cpp] view plaincopy
- #pragma comment(lib,"Linklib.lib")
- #include "../../Linklib/Linklib/Test1.h"
[cpp] view plaincopy
- CTest1 ss;
- ss.A();
小結:
最終效果為程序均能夠正常運行。
RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成