1. 程式人生 > >C#中使用OpenGL:(三)將.lib檔案編譯為.dll檔案

C#中使用OpenGL:(三)將.lib檔案編譯為.dll檔案

C#不能呼叫C/C++lib檔案的函式,但能呼叫dll檔案的函式。可是現在的情況是,我只有一個lib檔案,函式的實現都在裡邊了。能不能把lib變為dll呢?答案是肯定的。
要把lib編譯為dll大概有三種方法吧:
第一種,就是把lib的函式封裝一下,然後用編譯器編譯為dll。具體做法就是,先定義一個函式,然後在函式內部引用lib中的函式,最後將函式輸出到dll檔案中。
例如:

void FUNC()
{
    func();//lib檔案中的一個函式被引用
}

這種做法容易想到,但不推薦這樣做。因為這樣做就是給lib中的函式加了一層殼,本來呼叫一次函式,相當於呼叫兩次,效率降低。
第二種,使用VS提供的工具lib.exe將lib的函式分離成obj檔案,然後使用link.exe工具將obj連線輸出為dll。這種方法比較麻煩,這裡不詳細介紹。
第三種,利用link.exe工具,直接將lib生成dll。這種方法相對簡單,而且很有效,所以,本文將詳細介紹這種方法。

將lib直接編譯為dll

在Visual studio 中,可以將函式輸出到dll檔案中,但我摸索了很久也沒能實現將lib直接轉為dll。我查了很多資料,發現VS提供的工具link.exe卻是可以直接將lib轉為dll的。
如果已經安裝了VS整合開發環境,那麼可以在VS安裝路徑下的VC/bin資料夾找到link.exe。例如我將VS安裝在C:\Microsoft Visual Studio 14.0目錄中,link.exe所在的位置:

C:\Microsoft Visual Studio 14.0\VC\bin

這個link.exe是可執行檔案,但不能直接執行,而要在命令列中執行。

如何使用link.exe?

要使用link.exe將lib輸出為dll,需要經過幾個步驟。
1.首先,要配置環境變數
將下面的路徑新增到使用者環境變數或系統環境變數Path中:
C:\Microsoft Visual Studio 14.0\VC\bin
C:\Microsoft Visual Studio 14.0\Common7\IDE
2.其次,在命令列中執行 C:\Microsoft Visual Studio 14.0\VC\bin目錄下的vcvars32.bat。

正確做完這兩步工作之後就可以使用link.exe工具將lib輸出位dll了,如果配置不正確,就會提示“無法開啟XXX.lib”等錯誤。
若想了解更多,可以參考:

http://blog.sina.com.cn/s/blog_842bf5cd01017a0k.html

3.第三,編寫def檔案。
def檔案用來告訴link.exe將要輸出那些函式。
首先新建一個文字檔案,檔名可以任意取,比如我命名為mydll。
然後,將字尾名改為def。於是整個檔案就變為mydll.def。
最後,編輯mydll.def檔案。檔案中包含如下內容:

LIBRARY "xxxx"
EXPORTS
函式一
函式二
函式三
.....

xxx就是你將要輸出的dll的檔名。EXPORTS後面是將要輸出的函式名,想要輸出多少函式,就寫多少。比如,mylib.lib檔案中的兩個函式為Add和Multi,我要將它們輸出到mydll.dll中,則def檔案可以這樣寫:

LIBRARY "mydll"
EXPORTS
Add
Multi

如果,不知道lib檔案中有哪些函式怎麼辦?這時可以使用VS提供的dumpbin.exe來檢視lib檔案的函式名。
開啟命令列視窗,輸入cd C:\Microsoft Visual Studio 14.0\VC\bin命令,可以將碟符移動到C:\Microsoft Visual Studio 14.0\VC\bin資料夾下,這樣命令列就可以執行dumpbin.exe了。

這裡寫圖片描述

輸入命令dumpbin “檔名” /ALL。檔名是將要檢視的檔名稱,字尾是lib、dll、obj的檔案都可以查。我要檢視myLib.lib中的函式名稱,操作如下:

這裡寫圖片描述

檢視結果:

這裡寫圖片描述

從檢視的結果來看,myLib.lib檔案中有兩個函式,函式名稱分別為_Add和_Multi。這兩個函式名稱被修飾了,都加了下劃線,原來應該為Add和Multi。

4.第四,寫好def檔案之後,下一步就是利用link.exe將myLib.lib中的函式輸出到mydll.dll中。為了方便起見,把mydll.def檔案和mylib.lib檔案都複製到C:\Microsoft Visual Studio 14.0\VC\bin資料夾下。然後在命令列中輸入命令:

//進入目錄C:\Microsoft Visual Studio 14.0\VC\bin
cd C:\Microsoft Visual Studio 14.0\VC\bin

//開啟批處理檔案vcvars32.bat
vcvars32.bat

//輸入link命令
link myLib.lib /DLL /DEF:mydll.def /OUT:mydll.dll

命令列進入某個目錄的命令是“cd”,後面跟目錄名稱。值得注意的是,使用link命令時,“/”前一定要有一個空格,否則命令將無法被識別。/DLL前有一個空格,/DEF前也有一個空格。

按回車,如圖:

這裡寫圖片描述

執行結果:

這裡寫圖片描述

如果命令輸入正確,那麼可以看到生成三個新的檔案:mydll.lib、mydll.dll 、mydll.exp。其中,mydll.dll就是我想要的東西。

這裡寫圖片描述

使用depends工具檢視mydll.dll中的函式,看看有沒有正確生成。

這裡寫圖片描述

可以看到,mydll.dll檔案中確實存在Add和Multi函式,而且對mydll.dll的呼叫也是成功的。這證明,通過命令列執行link.exe工具確實可以將lib檔案轉為dll檔案。

注意事項:

1.使用link.exe工具之前一定要配置好環境變數;
2.每次使用link.exe連線lib檔案都要先在命令列中開啟vcvars32.bat;

結語:

事實上,在網上下載的OpenGL庫,一般都包括了dll檔案,沒有必要費神將lib檔案轉化為dll檔案。OpenGL庫都有好幾百個函式,如果要一個個把函式名寫進def檔案中也是很費力氣的,而且很容易出錯。本文雖然研究瞭如何根據lib檔案生成dll檔案,但實際操作的過程中,我不會用這種方法將OpenGL的靜態連結庫轉化為動態連結庫,而是直接使用已有的dll。人都是懶惰的!