vc6.0 release版本下出現內容讀寫錯誤問題

本來在DEBUG下運行的非常好,可是換成release後就出現了各種的內存讀寫錯誤,話說在DEBUG下,沒有初始化的變量都被初始化爲零了,而在RELEASE下則是隨機數值,然後就各種查找錯誤,最後看到把動態鏈接庫改成靜態鏈接庫,我就試了一下,終於行了,哎,不得不說WINDOWS啊你不地道。。。

網上查了一下靜態鏈接庫和動態鏈接庫的區別,我簡單總結一下:

1、如果是靜態鏈接庫模式,程序是把目標代碼從庫文件拷貝到執行文件,這樣在DLL不在的情況下,程序依舊可以運行,動態則是運行過程中加載,前提是你要有DLL可以提供加載

2、明顯靜態模式下最終程序要大,而動態要小


遺憾地說:除了ender說的是正確的外,其他觀點都有偏頗之處甚至是錯誤的。我的感覺是,大家受MFC的影響太深了,而沒有看到事情的本質。 
首先糾正所謂“靜態連接就是把需要的庫函數放進你的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無法運行是不明智的。避免這樣的結局只有用動態鏈接。 

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