日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

隱式鏈接無.LIB動(dòng)態(tài)鏈接庫

 bluecrystal 2006-08-04

隱式鏈接無.LIB動(dòng)態(tài)鏈接庫

由于我們經(jīng)常要調(diào)用一些第三方廠商或其他編譯器編寫的動(dòng)態(tài)鏈接庫,但是一般都不提供源文件或.lib文件,而作為VC隱式鏈接到DLL(implicitly link to the DLL)調(diào)用,這些卻是必需的。本文將主要討論在沒有源文件..

     由于我們經(jīng)常要調(diào)用一些第三方廠商或其他編譯器編寫的動(dòng)態(tài)鏈接庫,但是一般都不提供源文件或.lib文件,而作為VC隱式鏈接到DLL(implicitly link to the DLL)調(diào)用,這些卻是必需的。本文將主要討論在沒有源文件及.lib輸入庫文件或欲調(diào)用Windows未公開函數(shù)的情況下重建.Lib文件的方法。在建立之前,我們首先要了解一下DLL輸出函數(shù)的幾種方式。
     一、從DLL中輸出函數(shù)的方式(calling conventions)
     _cdecl是C和C++程序的缺省調(diào)用方式。每一個(gè)調(diào)用它的函數(shù)都包含清空堆棧的代碼,所以產(chǎn)生的可執(zhí)行文件大小會(huì)比調(diào)用_stdcall函數(shù)的大。函數(shù)采用從右到左的壓棧方式。VC將函數(shù)編譯后會(huì)在函數(shù)名前面加上下劃線前綴。
     _stdcall是Pascal程序的缺省調(diào)用方式,通常用于Win32 Api中,函數(shù)采用從右到左的壓棧方式,自己在退出時(shí)清空堆棧。VC將函數(shù)編譯后會(huì)在函數(shù)名前面加上下劃線前綴,在函數(shù)名后加上"@"和參數(shù)的字節(jié)數(shù)。
     _fastcall方式的函數(shù)采用寄存器傳遞參數(shù),VC將函數(shù)編譯后會(huì)在函數(shù)名前面加上"@"前綴,在函數(shù)名后加上"@"和參數(shù)的字節(jié)數(shù)。
     用VC建立一個(gè)空的動(dòng)態(tài)鏈接庫,并加入以下三個(gè)文件:
     //noname.h  動(dòng)態(tài)鏈接庫頭文件
     extern "C" void _stdcall  stdcallproc(void);
     extern "C" void  _cdecl cdeclproc(void);
     extern "C" void  _fastcall fastcallproc(void);
     //noname.cpp   動(dòng)態(tài)鏈接庫實(shí)現(xiàn)文件
     #include
     extern "C" void _stdcall  stdcallproc(void)
     { MessageBox(0,"stdcall function","dll call",0);
     }
     extern "C" void  _cdecl cdeclproc(void)
     { MessageBox(0,"cdecl function ","dll call",0);
     }
     extern "C" void  _fastcall fastcallproc(void)
     { MessageBox(0,"fastcall function ","dll call",0);
     }
     //noname.def  動(dòng)態(tài)鏈接庫輸出函數(shù)定義
     LIBRARY      "noname"
     EXPORTS
     stdcallproc @1 noname
     cdeclproc  @2
     fastcallproc @3
     編譯后生成noname.lib,輸出函數(shù)_cdeclproc,_stdcallproc@0,@fastcallproc@0;生成的noname.dll在Exescope等PE格式的工具中只能看到cdeclproc和fastcallproc函數(shù),因?yàn)閟tdcallproc被指定noname屬性,沒有名字輸出,類似于Windows未公開函數(shù)。
     二、可執(zhí)行程序調(diào)用DLL的方式
     可執(zhí)行程序可以采用隱式鏈接(implicit linking)或顯式鏈接(explicit linking)兩種方式調(diào)用一個(gè)DLL。
     使用顯式鏈接時(shí),使用DLL的程序在使用之前必須加載(LoadLibrary)加載DLL從而得到一個(gè)DLL模塊的句柄,然后調(diào)用GetProcAddress函數(shù)得到輸出函數(shù)的指針,在退出之前必須卸載DLL(FreeLibrary),因?yàn)椴皇潜疚闹攸c(diǎn),具體例程請(qǐng)參考有關(guān)文檔。顯然,在調(diào)用大量的函數(shù)時(shí)這種方法會(huì)很不方便。
     使用隱式鏈接時(shí),可執(zhí)行程序鏈接到一個(gè)包含DLL輸出函數(shù)信息的輸入庫文件(.LIB文件)。操作系統(tǒng)在加載使用可執(zhí)行程序時(shí)加載DLL??蓤?zhí)行程序直接通過函數(shù)名調(diào)用DLL的輸出函數(shù),調(diào)用方法和程序內(nèi)部其他的函數(shù)是一樣的。
     三、重建.Lib輸入庫文件
     根據(jù)微軟的建議,要想隱式地鏈接到一個(gè)DLL,可執(zhí)行程序必須從DLL的提供者那兒得到一個(gè)包含輸出函數(shù)的頭文件(.h文件)、一個(gè)用于鏈接的輸入庫(.lib文件)。愿望是很好的,但是一般情況下,我們都無法得到第三方動(dòng)態(tài)鏈接庫的輸入庫文件,或者我們需要調(diào)用Windows未公開函數(shù)。如果你是使用Delphi或Visual Basic開發(fā)程序,那么,你只要簡(jiǎn)單的申明一下函數(shù)和輸出庫就可以了。但是,使用VC的朋友們只好重建.Lib文件了。
     1.刪掉第一步中生成的noname.lib(假設(shè)我們沒有這個(gè)文件)。
     2.用微軟的DumpBin.exe:dumpbin /exports noname.dll>noname.def,留下noname.def文件的輸出段:
         ordinal hint RVA      name
               2    0 00001005 cdeclproc
               3    1 0000100F fastcallproc
               1      0000100A [NONAME]
     修改為:
     LIBRARY      "noname"
     EXPORTS
     cdeclproc    @2
     fastcallproc @3
     nonameproc   @1 //請(qǐng)注意與第一步中noname.def的區(qū)別:nonameproc可以自己指定為任何名字
     再執(zhí)行l(wèi)ib.exe /def:noname.def即可生成noname.lib文件(但如果這個(gè)動(dòng)態(tài)鏈接庫不僅僅包含_cdecl類型函數(shù),那么這個(gè)noname.lib還不是最終可用的.lib文件,具體請(qǐng)看下文)。
     3.建立一個(gè)名為DllCaller的Win32控制臺(tái)程序,將剛才生成的noname.dll和noname.lib拷入DllCallerdebug目錄。
     //DllCaller.cpp
     //聲明函數(shù)原型
     extern "C" void _stdcall  nonameproc(void);
     extern "C" void  _cdecl cdeclproc(void);
     extern "C" void  _fastcall fastcallproc(void);
     //鏈接輸入庫文件
     #pragma comment(lib,"debug\noname.lib")
     int main(int argc, char* argv[])
     {
         nonameproc();
         cdeclproc();
         fastcallproc();
         return 0;
     }
     編譯器產(chǎn)生如下錯(cuò)誤:
     DllCaller.obj : error LNK2001: unresolved external symbol @fastcallproc@0
     DllCaller.obj : error LNK2001: unresolved external symbol _nonameproc@0
     根據(jù)錯(cuò)誤提示信息將noname.def更改如下:
     @fastcallproc@0 @3
     nonameproc@0 @1
     重新生成noname.lib,即可重新編譯DllCaller.exe。
     四、調(diào)用Windows未公開函數(shù)
     根據(jù)以上分析,下面給出一個(gè)簡(jiǎn)單的調(diào)用Window98系統(tǒng)Shell32.DLL中序號(hào)為60的未公開函數(shù),執(zhí)行后將出現(xiàn)重新啟動(dòng)的對(duì)話框。
     //shell32.def,據(jù)此生成Shell32.LIB
     LIBRARY      "shell32"
     EXPORTS
     SHShutDownDialog@4 @60
    
     // DllCaller.cpp:調(diào)用未公開函數(shù)的控制臺(tái)程序
     //函數(shù)聲明
     extern "C" long  _stdcall SHShutDownDialog(long lShutdown);
     //鏈接輸入庫文件
     #pragma comment(lib,"debug\shell32.lib")
     int main(int argc,char* argv[])
     {
        SHShutDownDialog(0);
     return 0;
     }
     本文所有程序在VC6.0,Windows98SE環(huán)境下調(diào)試通過,也希望這些程序?qū)τ谟肰C的朋友有所幫助。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多