動態鏈接庫與靜態鏈接庫

 

首先糾正所謂“靜態連接就是把需要的庫函數放進你的exe之中”的說法。在真實世界中,有三個概念:Use   static   libary,   static   linked   DLL,   dynamic   linked   DLL.   
  多數人混淆了static   libary   和   static   linked   DLL的概念,當然他們有似是而非的“相似之處”,比如都用到.lib,下面具體說明。   
          使用靜態庫(Use   static   libary)是把.lib和其他.obj一起build在目標文件中,目標文件可以是.exe,也可以是.dll或.oxc等。一般情況下,可以根本就沒有“對應的”.dll   文件,如C   Run   Time(CRT)庫。一個例子就是,寫一個main(){},build出來並不是只有幾個字節,當然有人會說那還有exe文件頭呢?是,即使加上文件頭的尺寸,build出的執行文件仍然“莫名的大”。實際上那多出來的部分就是CRT靜態庫。姑且可以把靜態庫.lib理解成外部程序的obj文件比較合理,它包含了函數的實現。   
          下面再談static   linked   DLL   和   dynamic   linked   DLL又如何?   
          靜態鏈接   (static   linked   DLL)從操作上在VC的Project|Settings...|Link   (tab)|General   (category)|Object/library   modules   中設置和添加。比如要使用SDK中的PropertySheet()   API,   就要在這裏添加   comctl32.lib,然後再調用的源程序中#include   <prsht.h>,   使用的地方直接調用PropertySheet()。當程序.exe啓動時,系統會把對應comctl32.dll加載進來。作爲DLL的靜態引入庫的.lib不包含函數的實現,只包含用於系統加載的信息,如對應的DLL名稱,函數歧視地只在對應的DLL中的便宜等等。相比動態鏈接而言,靜態鏈接是很簡單的。   
          動態鏈接是使用LoadLibrary()/GetProcessAddress()和FreeLibrary(),詳見下面的例子。   
    
          {   
                  typedef   BOOL     (WINAPI   *LPFNSHELLEXECUTEEX)(LPSHELLEXECUTEINFO);   
    
                  hShell32Dll   =   LoadLibrary(TEXT("SHELL32.DLL"));   
                  if   (!hShell32Dll)   {   goto   End;   }   
    
                  lpfnShellExecuteEx   =   (LPFNSHELLEXECUTEEX)GetProcAddress(hShell32Dll,   
                          API_NAME(ShellExecuteEx));   
                  if   (!lpfnShellExecuteEx)   {   goto   End;   }   
    
                  ...   
                  fOk   =   (*lpfnShellExecuteEx)(pShellExecuteInfo);   
                  ...   
          End:   
                  if   (hShell32Dll)   {   
                          FreeLibrary(hShell32Dll);   
                  }   
                  lpfnShellExecuteEx   =   NULL;   
                  ...   
          }   
  有人會想,動態鏈接這樣麻煩,爲什麼還要用呢?這裏有一個技術問題,對這個問題的解決直接導致了動態加載的需求。問題是有些DLL只在某個Windows版本中存在,或某個API只在某些Windows版本中被加入指定的DLL。當你使用靜態鏈接的.exe試圖在不支持的Windows版本上運行時,系統會彈出系統對話框提示某某.dll無法加載或無法定位某某API的消息,然後就中止.exe的運行。像這樣因爲個別功能的實現依賴於某個DLL,當這個DLL不可用時導致整個.exe無法運行是不明智的。避免這樣的結局只有用動態鏈接。  


=============
不能運行是原因是沒有MFC的動態鏈接庫,只要把你的程序在需要的幾個動態鏈接庫一併拷到目標機器上就行了。   
    
  或者用靜態鏈接到MFC   
  project   properties->configuration   properties->general,在user   of   mfc中選擇use   mfc   in   a   static   library
=============

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