文章編號: 106553 - 上次校閱: 2004年7月15日 - 版次: 2.1 如何撰寫 C DLL 及呼叫從 Visual Basic
在此頁中結論這篇文章概述如何與 Visual Basic 使用 DLL。它涵蓋了下列問題: 區段 A
區段 B
其他相關資訊區段 a1.0 什麼是 DLL?DLL (動態連結程式庫) 都是 Windows 中重要的層面。DLL 包含可執行的程式可以在執行期間呼叫的函式。 亦即 DLL 會為您的程式可以動態地連結使用的函式的程式庫。連結可以是靜態或動態。靜態連結並不會改變。您的程式存取程式庫函式所需的所有地址資訊被固定的可執行檔建立和執行期間保持不變。 視需要建立動態連結。當程式所需的函式不是在可執行檔,Windows 載入動態連結程式庫 (DLL) 可以其函式的所有應用程式中使用。到那個時候 Windows 解析每個函式的位址,並動態連結至您的應用程式。 在 Visual Basic 中使用的所有自訂控制項都是 DLL。唯一的差別在於它們需要特殊處理方面的 Visual Basic 從收到郵件。 1.1 為什麼使用 DLL?以下是您為何想要使用 DLL 的四個原因:
1.2 的分解架構的 DLL每個 DLL 必須包含 LibMain 函式,且應包含除了匯出可由可執行程式呼叫的函式一個 Windows 的 [結束程序 (WEP)。
1.3 DLL 記憶體管理問題使用大量記憶體模型。C 會儲存所有變數定義為靜態或全域 (定義函式之外) 在程式的堆積空間和 C 都儲存所有其他變數在堆疊上。 小型和中型] 模型中所有指標附近都是根據預設值。這表示資料由 16 位元位移,資料區段 (DS) 暫存器,或堆疊區段 (SS) 登錄存取。不幸的是,編譯器有無法知道位移會從 DS 或 [SS。在大多數程式中這不會有問題因為 DS 和 SS 指向相同的區段。一個 DLL 不過,是一種特殊情況。 DLL 有它自己的資料區段,但是與呼叫程式共用其堆疊。這表示 DS 及 [SS 未指向相同的位置。此問題最簡單的解決方案是建置 DLL 在大型記憶體模型中所有變數在 32 位元值所都參考的位置。 為什麼動態配置的記憶體嗎?動態配置的記憶體是一項 Windows 友善的技巧。宣告大型陣列資料佔用的空間也就是限於 64K 的程式的堆疊或您程式的資料區段會浪費磁碟空間和 Windows 記憶體中。最好時需要或當您完成時再釋放要求記憶體 Windows。配置記憶體在 Windows 中,您可以動態地配置兩種類型的記憶體區域和全域。本機記憶體是限制為 64 K,與呼叫 DLL 的程式在一個 DLL 的情況下共用本機記憶體。它已經載入之後,全域記憶體就是記憶體的所有 Windows 可用。配置本機記憶體及 Managed 使用 LocalAlloc、 LocalLock LocalUnlock 和 LocalFree 運作--如下例所示: 全域記憶體配置及管理使用 GlobalAlloc、 GlobalLock GlobalUnlock 和 GlobalFree 運作--如下例所示: 如果想共用 DLL 與其他程式中配置記憶體應該配置它使用 GMEM_SHARED 旗標。如果想共用透過 DDE 記憶體必須將它配置使用 GMEM_DDESHARE 旗標。 在靜態變數中儲存資料時請小心如果嘗試將資料儲存於 DLL,使用全域或靜態變數中不要是感到驚訝,如果這些值已經變更當您接下來呼叫您的 DLL。儲存在這種方式,資料會通用於所有存取此 DLL 的應用程式。不論多少應用程式使用 DLL,沒有 DLL 的只有一個執行個體。若要解決這個問題,最好是從 DLL 傳回結構,並一次傳遞它們在中,在需要時。檔案控點您不可能共用應用程式或 DLL 之間的檔案控制代碼。每一個應用程式有它自己的檔案控制碼表格。兩個應用程式可以使用相同的檔案使用 DLL,他們必須兩者都開啟的檔案個別。1.4 建置 DLL,使用 Visual C++以下是建置 DLL,使用 Visual C++ 的必要步驟:
1.5 範例 C DLL下列的 DLL 包含 GetDiskInfo 函式可從 Visual Basic 呼叫。它會傳回可用磁碟空間、 目前的磁碟機名稱和磁碟區名稱。LIBRARY diskinfo 注意: LIBRARY 名稱在.DEF 檔必須做為 DLL 檔案名稱相同或其他 Visual Basic 會提供您 「 錯誤中載入的 DLL 」。比方說建立檔案 DISKINFO.DLL 使用上述的.DEF 檔中 LIBRARY DISKINFO 陳述式。 描述 ' GetDiskInfo 罐從呼叫 Visual Basic ' EXETYPE 視窗 3.1 程式碼 PRELOAD MOVEABLE 可捨棄 資料 PRELOAD 可移動單 HEAPSIZE 4096 匯出 GetDiskInfo @ 1 區段 b從 Visual Basic 呼叫 DLL 的 2.0在 Visual Basic 所有函式中包括您想要呼叫 DLL 函式必須先宣告使用 Declare 陳述式。您可以宣告您在表單或模組的宣告區段中的函式。如果宣告 DLL 程序或在表單中的函式是私用到該表單。 若要使其公用,您必須在模組中宣告。下列是範例 Declare 陳述式:一旦您宣告函式時,您可以呼叫,並使用函式,方式就會呼叫和使用 Visual Basic 函數一樣。 2.1 DLL 參數由於 DLL 通常以 C 撰寫,DLL 可以使用各種不同的參數不直接支援 Visual Basic 的。如此一來當傳遞參數,程式設計人員尋找傳遞適當資料型別。傳遞引數傳值方式或傳址預設情況下,Visual Basic 會由參考傳遞所有引數。(當以傳址方式傳遞,Visual Basic 提供 32 位元的遠程位址)。不過,許多 DLL 函式預期要傳值方式傳遞的引數。這將可達到藉由放置 ByVal 關鍵字引數宣告的前面。下列各節將告訴您,如何將參數轉換成 Visual Basic。 8 至 16 位元數值參數(int、 簡短、 不帶正負號的 int、 不帶正負號的短整數、 BOOL 及 WORD) 8 至 16 位元數值參數傳遞為整數。32 位元數值參數32 位元數值參數傳遞 (長,未簽署長時間和 DWORD) 作為 LONG。物件控點所有的控點是與視窗相關聯的唯一的 16 位元的整數值,並傳值方式傳遞,所以這些參數傳遞為整數。字串字串包含 LPSTR 和 LPBYTE 資料類型 (字元的指標) 或不帶正負號字元的指標。這些參數傳遞為 (ByVal paramname 為 String)。要直接傳遞 Visual Basic 字串,將當做 (param 為 String) 傳遞它們。如需有關 Visual Basic 和 C DLL 之間傳遞字串的詳細資訊,請參閱 「 Microsoft 知識庫 」 中下列文: 118643?
(http://support.microsoft.com/kb/118643/EN-US/
)
如何 VB 和 C DLL 之間傳遞字串或字串陣列 注意: Visual Basic 字串需要特殊處理因此不要傳遞字串直接除非 DLL 明確要求。 數字值的指標只需不使用 ByVal 關鍵字,將指標傳遞到數字值。結構如果 Visual Basic 使用者定義型別符合該 DLL 所預期的結構,結構可以以傳址方式傳遞。注意: 結構不能以傳址方式傳遞值。 陣列的指標以傳址方式傳遞陣列的第一個項目。函式的指標Visual Basic 不支援回呼函式,因此有指標的函式的 DLL 函式不能與 Visual Basic 一起使用。null 指標如果 DLL 所預期 Null 指標,將它當做 (ByVal paramname As Any) 傳遞。您可以使用 0 做為 paramname 呼叫 DLL 時的值 (& I)。2.2 疑難排解以下是一些您可能會遇到的問題的解決方案。呼叫 DLL 之後,系統資源保留取得較低如果您的 DLL 使用 GDI 物件,您必須記得要釋放之後使用它們。這可能不是在 Visual Basic 中明顯,但如果您建立 GDI 物件 (比方說 CreateBrushIndirect),請使用 Windows SDK (軟體開發套件) 時, 必須刪除它稍後使用 DeleteObject。無效的 DLL 呼叫慣例錯誤這項錯誤是通常因不正確地省略或包括 ByVal 關鍵字從 Declare 陳述式。如果傳遞錯誤參數,也可能引起這個錯誤。載入 DLL 時發生錯誤當您呼叫動態連結程式庫程序,而且不能載入程序的 Declare 陳述式中所指定之檔案時,就會發生這個錯誤。您可以使用 Microsoft Windows API 函數 LoadLibrary 以找出有關為何無法載入一個 DLL 更特定資訊。一般性的保護 (GP) 錯誤當您的程式將寫入至不屬於它的記憶體區塊時,就會發生 GP 錯誤。這兩個最可能原因包括:
2.3 範例 Visual Basic 呼叫程式有兩個部分 Visual Basic 程式中呼叫的 DLL。首先宣告在函式,然後在事件程式碼中使用它。以下是 Declare 陳述式的範例。Declare 陳述式應該將放在模組或表單的一般宣告區段。 一旦宣告函式可在事件程式碼中使用它。下列範例會使用從 DLL 函式 Command1 Click 事件程式碼中: 這篇文章中的資訊適用於:
機器翻譯重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。 按一下這裡查看此文章的英文版本:106553?
(http://support.microsoft.com/kb/106553/en-us/
)
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。 | 其他資源 其他支援網站社群立即取得協助文章翻譯
|






Windows Live
Facebook
Twitter
Linkedin
Digg it
Yahoo
Delicious
StumbleUpon
Yammer
Reddit
Technorati
FriendFeed
Email



回此頁最上方
