動態鏈接庫和靜態鏈接庫的區別

靜態連接庫就是把(lib)文件中用到的函數代碼直接鏈接進目標程序,程序運行的時候不再需要其它的庫文件;動態鏈接就是把調用的函數所在文件模塊(DLL)和調用函數在文件中的位置等信息鏈接進目標程序,程序運行的時候再從DLL中尋找相應函數代碼,因此需要相應DLL文件的支持。  

靜態鏈接庫與動態鏈接庫都是共享代碼的方式,如果採用靜態鏈接庫,則無論你願不願意,lib 中的指令都全部被直接包含在最終生成的 EXE 文件中了。但是若使用 DLL,該 DLL 不必被包含在最終 EXE 文件中,EXE 文件執行時可以“動態”地引用和卸載這個與 EXE 獨立的 DLL 文件。靜態鏈接庫和動態鏈接庫的另外一個區別在於靜態鏈接庫中不能再包含其他的動態鏈接庫或者靜態庫,而在動態鏈接庫中還可以再包含其他的動態或靜態鏈接庫。


“每一個lib文件就是若干函數(假設只有函數)的定義” 
lib庫有兩種,一種是包含了函數所在DLL文件和文件中函數位置的信息,稱爲導出庫;一種是包含函數代碼本身,一般現有的DLL,用的是前一種庫;以前在DOS下的TC/BC等,是後一種庫。包含函數原型聲明的,是頭文件(.h)。  

  lib有靜態lib和動態lib之分。

  靜態lib將導出聲明和實現都放在lib中。編譯後所有代碼都嵌入到宿主程序

  動態lib相當於一個h文件,是對實現部分(.dll文件)的導出部分的聲明。編譯後只是將導出聲明部分編譯到宿主程序中,運行時候需要相應的dll文件支持


  
“通過#include包含這些函數聲明的頭文件後,我們的應用程序就可以使用lib文件中的函數”

還要指定編譯器鏈接相應的庫文件。在IDE環境下,一般是一次指定所有用到的庫文件,編譯器自己尋找每個模塊需要的庫;在命令行編譯環境下,需要指定每個模塊調用的庫。 

“那他和直接給出那個函數定義的文件,比如.cpp文件,和頭文件有什麼區別,靜態鏈接庫有什麼用” 
cpp文件是源代碼,庫文件是編譯後的二進制代碼,比如你可以調用Windows的API,但是不能看到其源代碼一樣。 

“還有不明白的是,靜態鏈接庫中的lib文件只要用到,則整個lib文件的內容都放進了exe文件中,那它是被編譯進去還是鏈接的時候連接進去的呢?” 
是在鏈接的時候將lib鏈接到目標代碼中。

 

靜態鏈接庫(Lib)
在VC++6.0中new一個名稱爲libTest的static library工程,

並新建lib.h和lib.cpp兩個文件,lib.h和lib.cpp的源代碼如下:

//文件:lib.h
#ifndef LIB_H
#define LIB_H
extern "C" int add(int x,int y);   //聲明爲C編譯、連接方式的外部函數
#endif

//文件:lib.cpp
#include "lib.h"
int add(int x,int y)
{
return x + y;
}


  編譯這個工程就得到了一個.lib文件,這個文件就是一個函數庫,它提供了add的功能。將頭文件和.lib文件提交給用戶後,用戶就可以直接使用其中的add函數了。

  標準Turbo C2.0中的C庫函數(我們用來的scanf、printf、memcpy、strcpy等)就來自這種靜態庫。

下面來看看怎麼使用這個庫,在libTest工程所在的工作區內new一個libCall工程。libCall工程僅包含一個main.cpp文件,它演示了靜態鏈接庫的調用方法,其源代碼如下:

 

 

#include <stdio.h>
#include "../lib.h"//不可丟失
#pragma comment( lib, "..//debug//libTest.lib" )  //指定與靜態庫一起連接
int main(int argc, char* argv[])
{
printf( "2 + 3 = %d", add( 2, 3 ) );
}


  靜態鏈接庫的調用就是這麼簡單,或許我們每天都在用,可是我們沒有明白這個概念。代碼中#pragma comment( lib , "..//debug//libTest.lib" )的意思是指本文件生成的.obj文件應與libTest.lib一起連接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章