DLL導出lib文件和.h頭文件

   最近工作中遇到需要調用別人的動態鏈接庫,但是隻有個dll文件,別的一概沒有,這可怎麼辦呢。還有不少dll導出的都是類,直接顯式調用不太方便,最後綜合網上的辦法,自己再寫兩個工具,終於實現了將dll導出lib文件,並同時生成.h頭文件。
    
    還是自己動手才能豐衣足食啊。

=========================================================================

問題:如果手上只有一個DLL文件,沒有lib文件.h頭文件,程序裏怎麼調用它

方法當然很簡單,
先用VC的工具Depends.exe查看導出函數的函數名啊
用IDAPro或者其他反彙編工具分析函數原型
再用API函數:LoadLibrary,GetProcAddress
完成!

但是……如果Dll導出的是一個個的類呢,這就稍微有點麻煩

========================================================================

方法1:還是用顯式調用,LoadLibrary,GetProcAddress,
這時候就要在頭文件裏聲明一個個的“類成員函數的函數指針”了,
把GetProcAddress返回值賦給這些指針,使用時調用指針即可。

如何知道類的成員函數原型是長什麼樣的呢?
還是Depends工具,如果直接看,會發現導出函數名中有好多"?","@"等符號,

Depends的上面有個按鈕"C++"(如果沒有這個按鈕,說明你的Depends太老了,下載個新的吧),點了這個按鈕,再看看函數名有啥變化,是不是變得比較好理解了
不過Depends解析得還不夠完全,看不出來成員函數是public、protected還是private,也不知道調用約定是__cdecl、__stdcall還是__fastcall,是虛函數還是靜態成員函數。
如果要知道這些,還是用VC的undname.exe看得比較全面。

=======================================================================

方法2:用lib文件進行隱式鏈接,這樣無需LoadLibrary,個人感覺比較方便的
如何生成lib文件呢,假設動態鏈接庫名爲example.dll,步驟如下

1、執行dumpbin.exe/EXPORTS example.dll>example.def
生成了一個def文件,裏面的內容大概是下面這樣:
   ordinal hint RVA      name
       1    0 00004570?function1@@
       2    1 00004540?function2@@

2、編輯這個def文件,刪掉沒用的信息,將它整理成這樣的格式 :
        LIBRARY "example"
        EXPORTS
        ?function1@@    @1
        ?function2@@    @2
上面的@1和@2是根據第1個步驟中的ordinal序號來的

這個步驟我寫了個程序HandleDef.exe來自動修改,否則太多函數的話手動改就累死了

3、運行lib.exe/def:example.def
生成了example.lib和example.exp文件。這個lib文件就可以在VC裏用了,
比如這樣    #pragma comment(lib,"example.lib")

4、新建一個文件example.tmp,裏面保存函數名
?function1@@
?function2@@
然後運行undname.exeexample.tmp>example.txt
這樣函數名就解析到example.txt文件裏了

5、自己寫了個HandleTxt.exe程序,把example.txt轉換爲example.h
轉換後變成類似下面這樣:

1.       class __declspec(dllimport) CExample  

2.       {  

3.       public: int function1(void);  

4.       public: void function2(char);  

5.       };  

這個樣子的基本就能直接拷到VC裏用了。
不過,如果自己的程序要用到構造函數來新建一個對象的話,對導入類進行聲明的時候要事先分析好類對象的內存分佈(這可不是個簡單的事啊),上面這個CExample類應該這樣聲明

1.       class __declspec(dllimport) CExample  

2.       {  

3.       public: int function1(void);  

4.       public: void function2(char);  

5.       public: BYTE m_data[256];  

6.       };  

//上面m_data具體多少個字節,要靠自己反彙編分析,沒法自動生成,具體方法比較麻煩,有興趣的可以去網上查一些C++類的反彙編資料。

==========================================
總結:
爲了方便,把以下內容寫到一個批處理文件中
set name=example

dumpbin.exe/EXPORTS %name%.dll>%name%.def
HandleDef.exe %name%.def
lib.exe /def:%name%.def /MACHINE:IX86
undname.exe %name%.tmp>%name%.txt
HandleTxt.exe %name%.txt

執行完之後生成lib文件和h文件。
=========================================

上面提到的HandleDef.exe和HandleTxt.exe是我自己用C#寫的小程序。

寫了這麼多,也不知道有沒有人會感興趣。

注:我這個還只是適用於VC編寫的dll導出的類

如果用extern"c"導出的函數,除了自己反彙編分析原型,貌似沒有別的辦法

如何調用非VC編譯器編譯出來的類,暫時未研究過。


 

下載地址:http://pan.baidu.com/netdisk/singlepublic?fid=795627_2574562052

 

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