2009年7月25日 星期六

Hello DLL - 2初嚐Win32DLL

專案名稱:VCDll
目的:
一、將自己以前作的Win32 Static Link Libary,變成Win32 Dynamic-Link Library(DLL)
二、示範將一些標準函式庫輸出
(也可以解決OpenCV在BCB6下的問題 >"< => 找不到cvhaartraining.dll的run-time error)

方法:

1.用精靈新增一Win32 Dynamic-Link Library專案
選擇「A DLL that exports some symbols」 (因為會自動產生所需檔案 :p )

2.將 VCLib.h 和 VCLib.lib (於build VCLib專案後產生)
複製到VCDLL專案的目錄下,並加入專案中(使用方案總管)

3.在stdafx.h中 #include "VCLib.h" 及一些標準函式庫

4.常見的.h寫法
(VCDLL是這個例子的專案名稱,其它的開發環境或專案可用能的是 WIN32_API)

#ifdef VCDLL_EXPORTS
#define VCDLL_API __declspec(dllexport) //export dll時用
#else
#define VCDLL_API __declspec(dllimport) //import dll時用
#endif

a.當include這個.h檔,要export dll時
編譯器會自動加上相關的編譯參數而#define VCDLL_EXPORTS
(VC "專案屬性 =>C/C++ =>前置處理器" 中的設定 或 BCB的-WD編譯參數)
以使用 __declspec(dllexport)

b.當include這個.h檔,要import dll時
因為沒有#define VCDLL_EXPORTS,故使用 __declspec(dllimport)

6. 將欲export的函式宣告放在 extern "C" { ... }
Q:啥米係 extern "C" ? (自問自答中…)
A:編譯時將函式自動更改成不同名(依compiler而不同),稱為『name mangling
在函式的宣告前加上extern "C"這個修飾詞,
強制將函式名稱以C語言的形態重現,而非以C++語言的形態出現

如此一來就可以防止name mangling造成 :
在其它compiler要import同一個dll時會出問題 (例如VC下的dll/lib 要給 BCB用 =__=")


但是要注意,多載函式不能加上extern "C"這個修飾詞
(不然的話,有好幾個函式都同名,要link哪一個?
overloading function在compile-time就是用 name mangling 的方法實作,以便link時不會出錯)

7.在VCDll.cpp中加入程式碼,為了展示dll的實作
只將函式名稱更改或變大寫後,然後呼叫原函式
(將好幾顆水餃包成一個大包子,好吃嗎?)


註:除了上述步驟,其它的參考程式碼皆為VC的專案精靈產生
VC展示了:匯出 "變數"、"函式"、"類別建構式" 的範例程式碼
而在//---Tony----註解後的部分是自行加入的程式碼

ps2. 很久以前就想買了,但那時的大學生活太精彩了,沒錢也沒閒(一不小心就透露年紀了)
ps3. 雖然也出了好一陣子,但對一個上班族來說還是有點貴,有小錢但更沒閒
ps4. 退休時再來玩吧…
嗯…離題了

8. Build專案後可以得到VCDll.lib及VCDll.dll (怎麼用?下回再分解…)
一般在VS開發程式的習慣是:改好程式碼後就按[綠色小三角] (開始偵錯(F5))
此時VS會Build,當沒有error時執行build好的「執行檔」(.exe)

可是這個專案的「成品」不是.exe,而是 .dll及 .lib,
所以VS會跳一個視窗出來叫你選一個「偵錯工作階段時」的可執行檔

為了避免麻煩還要取消視窗,請忍住不要去點[播放]鍵,而直接按[F7]來建置(Build)方案
不然「哇辛卡北媚,跪閃關…」的歌聲可能真的會從喇叭傳出來…

沒有留言:

張貼留言