1. 程式人生 > >關於MFC中DLL的製作和呼叫

關於MFC中DLL的製作和呼叫

在做MFC程式的時候用到了DLL,所以查詢總結了一下。

一. 製作DLL流程

  • 為什麼都沒有段落符號與標號。。。
  • 先建立DLL工程、類,編寫DLL函式;編譯連結產生DLL檔案(普通工程產生的EXE檔案,DLL產生的是DLL檔案)。
  • 此時DLL檔案還不能呼叫。應用程式要想訪問某個DLL中的函式,那麼該函式必須是已經被匯出的函式。檢視DLL中有哪些匯出函式可用命令列工具:Dumpbin。命令如下:dumpbin回車—>dumpbin -exports 檔名.dll回車。
  • 這時可以看到沒有匯出函式。為了讓DLL匯出一些函式,需要在每一個將要被匯出的函式前面加識別符號: _declspc(dllexport)(如:_declspec(dllexport) add(int a, int b){})。再次編譯連結後產生兩個新檔案。一個是檔名.lib,即引入庫檔案;另一個是檔名.exp,不重要。這時再用dumpbin命令檢視,可以看到有了匯出函式。
  • 然後就可以呼叫DLL了,利用extern宣告外部函式。編譯連結呼叫函式。
  • 編譯通過,連結出錯。因為找不到庫檔案。此時將檔名.lib複製到呼叫程式所在目錄下,然後在VC中選擇Project\Settings選單命令,在開啟的對話方塊中選擇link選項卡,在Object\library module選項中輸入檔名.lib。
  • 再次build,這時可以用dunpbin -import 檔名.exe 來檢視呼叫程式生成的exe檔案的輸入資訊以及載入的DLL資訊。
  • 編譯執行又出錯了,這次是因為呼叫DLL檔案不在呼叫目錄中,也就是說它既不在該工程的執行目錄中,也不在工程所在目錄中(工程的執行目錄是指寫在工程配置中的目錄,工程所在目錄就是工程所在Debug資料夾),也不在系統目錄中(system、system32等),也不在path環境變數包含的路徑中(這四個路徑是VC呼叫檔案一次會先後遍歷的幾個路徑)。將呼叫的DLL檔案複製到該工程的Debug資料夾中即可。

二. 隱式呼叫DLL中函式的匯入與匯出

這部分內容,和上面的內容差不多,但主要出自《VC++深入詳解》,其中更深入地對DLL的呼叫進行了分析和優化。上面的內容是最原始最基礎的製作和匯入匯出原理,而以下則是在那基礎上的進一步優化,添加了一個頭檔案。而在實際從VC中建立工程時,一切都是便利的,已經包含了的,標頭檔案是現成的。只需要新增到呼叫DLL的工程中即可。
  1. 匯出:編寫好DLL檔案之後,要想使用它的函式必須先進性匯出,此時就要在函式定義前加 _declspec(dllexport);
  2. 匯入:應用程式要想使用dll的函式必須在使用前利用extern宣告外部函式,然後才能用。而這裡的extern可以用 _declspec(dllimport)代替。兩者相比,後者是呼叫動態連結庫專用,編譯器生成的程式碼更高效;
  3. 匯入匯出的說明的新增可以一次性完成,這個方法就是建立一個頭檔案。DLL中需要 _declspec(dllexport),則在dll中#define   DLL_API    _declspec(dllexport),然後#include  “標頭檔案名.h”呼叫該標頭檔案,而標頭檔案中函式的宣告前新增DLL_API即可。應用中需要 _declspec(dllimport),則在標頭檔案中#ifdef   DLL_API    #else   #define     DLL_API  _declspec(dllimport),然後在應用cpp中 #include “標頭檔案名.h”呼叫該標頭檔案即可。利用標頭檔案將 _declspec(export)和 _declspec(import)的新增都歸集到標頭檔案中,DLL檔案和應用檔案中的具體函式實現和引用就不需要再添加了。
注意:a.此方法是將引用宣告變為了預編譯指令,極大地簡化了引用過程;            b.標頭檔案的另一個好處是將動態庫的函式提前做了宣告,這樣可以讓使用者直觀明瞭地知道動態庫中的箇中函式功能;            c.標頭檔案也需要和.lib、.dll、一同新增到應用程式資料夾中,標頭檔案不是新增到配置中而是引入到工程中; 過程圖解:圖解做不出來。。。。改天上圖吧。