2010年12月9日 星期四

DLL的製作和使用

在程式開發上, 常會將自己寫好的共用函式或共用類別編譯成DLL, 這樣除了可以省記憶體空間外, 也可達到模組化方便讓其他程式共用, 這邊寫了一篇文章來介紹DLL建立的流程,主要分成兩個重點:

1.    DLL建立的步驟
  • 如何建立DLL檔(以C3DMath.dll為例)
  • 如何引用別人的lib檔和h檔(以MainDLLTest.exe為例)

2.    編譯環境的設定
VC中可以利用一些巨集指令來設定編譯環境,其優點有:
  • 方便管理檔案
  • 省去人工複製的時間(可以少掉複製一些h檔、 dll檔和lib檔的時間)
  • 將來可用在Auto build機制上


DLL建立的步驟-

1.    建立C3DMaths DLL專案:
開啟VC點選File -->New-->Project-->Win32 Console Application,然後在Name的欄位輸入專案的名稱


 2.    點選Next

3.    選擇DLL,然後按Finish


4.    產生一個標頭檔(C3DMath.h), 並加入下面這段巨集指令, 如下所示:
#ifdef  API_BUILD_DLL
 #define C3DMATHS_CLASS __declspec(dllexport)
#else
 #define C3DMATHS_CLASS __declspec(dllimport)
#endif

上面這段巨集的意思是, 如果定義了API_BUILD_DLL 編譯時就把字串 C3DMATHS_CLASS換成__declspec(dllexport), 否則, 就換成 __declspec(dllimport), 因為C3DMath.h 通常會用在兩個地方:
(1)產生 DLL的專案: 需要匯出 DLL 的資料、函式、類別或類別成員函式,因此要使用__declspec(dllexport)
(2)使用 DLL 的專案(例如exe檔): 此時需要匯入DLL 的資料、函式、類別或類別成員函式, 所以要用 __declspec(dllimport)

5.    在Preprocessor Definitions中定義巨集(API_BUILD_DLL),其作用是讓上面的巨集指令知道此DLL專案要使用__declspec(dllexport)

6.    在class的title上加上巨集的定義(C3DMATHS_CLASS), 表示將此class匯出

class  C3DMATHS_CLASS  C3DVector
{

public:
    C3DVector(void);
    ~C3DVector(void);

    C3DVector(float X, float Y, float Z);
    void Set(float X, float Y, float Z);
    float Length(void);
    void Normalize(void);
}

7.    按下Rebuild Sloution 鍵,即可產生C3DMaths.dllC3DMaths.lib

APP使用DLL的步驟
程式中使用DLL需要有.h檔, .lib檔和.dl檔, 其中.h檔和.lib檔必須加入到使用DLL的專案中, 而.dll檔則需要放在應用程式所在的路徑(通常和.exe檔同一路徑), 步驟如下:

1.    建立一隻Console的程式(MainDLLTest.exe)
2.    將C3DMath專案所產生的h檔、lib檔,複製到MainDLLTest的專案底下
3.    引入標頭檔(C3DMath.h)
       #include ".\C3DMaths\C3DMath.h"
4.    連結lib檔
       點選Property Page-->Linker-->Input-->Additional Dependencies,然後輸入lib檔的路徑


5. 複製.dll檔(C3DMaths.dll)到應用程式執行路徑下(MainDLLTest.exe), 即可執行程式來測試DLL的功能



編譯環境的設定
VC中可以利用一些巨集指令來設定你的編譯環境,不但可方便管理專案,也節省很多人工的時間,尤其在開發大型專案時,自動build的流程就變得很重要。下面介紹的方法,可用來自動產生使用DLL時,所要引用的檔案和資料夾,如此一來可省去人工複製的麻煩和時間。

首先看一下VC項目設置中可以使用的巨集,常用的有:

 1.    設定dll檔的輸出路徑
General -->Output Directory -->  $(PlatformName)\$(ConfigurationName)

2.    設定lib檔的輸出路徑
Linker->Advance->ImportLibrary -->\$(PlatformName)\$(ConfigurationName)/$(TargetName).lib

3.    利用Post Build Event複製檔案
這個功能大多是當你在開發 DLL 專案,編譯完成後,直接將編譯結果複製到會使用的專案目錄中。這樣就不用, 每次還要開檔案總管進行複製了。輸入的指令如下所示

產生專案目錄
mkdir  ".\$(ProjectName)" 

產生Debug或Release目錄
mkdir  ".\$(ProjectName)\$(PlatformName)\$(ConfigurationName)"

複製lib檔
COPY".\$(PlatformName)\$(ConfigurationName)\$(TargetName).lib"   
       ".\$(ProjectName)\$(PlatformName)\$(ConfigurationName)"

複製dll檔
COPY "$(TargetPath)" ".\$(ProjectName)\$(PlatformName)\$(ConfigurationName)"

複製h檔
COPY "C3DMatrix.h" ".\$(ProjectName)" 
COPY "C3DVector.h" ".\$(ProjectName)"                                                                                             
COPY "C3DMathLoader.h" ".\$(ProjectName)"        

沒有留言:

張貼留言