一 、引 言
由於windows為微機提供了前所未有的標準使用者介面、圖形處理能力和簡單靈便的操作,絕大多數程式編制人員都已轉向或正在轉向windows程式設計。在許多使用者設計的實際應用系統的程式設計任務中,常常要實現軟體對硬體資源和記憶體資源的訪問,例如埠i/o、dma、中斷、直接記憶體訪問等等。若是編制dos程式,這是輕而易舉的事情,但要是編制windows程式,尤其是windowsnt環境下的程式,就會顯得較困難。
因為windows具有"與裝置無關"的特性,不提倡與機器底層的東西打交道,如果直接用windows的api函式或i/o讀寫指令進行訪問和操作,程式執行時往往就會產生保護模式錯誤甚至宕機,更嚴重的情況會導致系統崩潰。那麼在windows下怎樣方便地解決上述問題呢?用dll(dynamic link libraries)技術就是良好途徑之一。
dll是windows最重要的組成要素,windows中的許多新功能、新特性都是通過dll來實現的,因此掌握它、應用它是非常重要的。其實windows本身就是由許多的dll組成的,它最基本的三大組成模組kernel、gdi和user都是dll,它所有的庫模組也都設計成dll。凡是以.dll、.drv、.fon、.sys和許多以.exe為副檔名的系統檔案都是dll,要是開啟windows/system目錄,就可以看到許多的dll模組。儘管dll在ring3優先順序下執行,仍是實現硬體介面的簡便途徑。dll可以有自己的資料段,但沒有自己的堆疊,使用與呼叫它的應用程式相同的堆疊模式,減少了程式設計設計上的不便;同時,乙個dll在記憶體中只有乙個例項,使之能高效經濟地使用記憶體;dll實現的**封裝性,使得程式簡潔明晰;此外還有乙個最大的特點,即dll的編制與具體的程式語言及編譯器無關,只要遵守dll的開發規範和程式設計策略,並安排正確的呼叫介面,不管用何種程式語言編制的dll都具有通用性。例如在bc31中編制的dll程式,可用於bc、vc、vb、delphi等多種語言環境中。筆者在bc31環境下編譯了windows下直接記憶體訪問和埠i/o兩個dll,用在多個自製系統的應用軟體中,執行良好。
二、dll的建立和呼叫
dll的建立及呼叫方法在許多資料上有詳細的介紹,為了節省篇幅,在這裡僅作一些主要的概括。
1.dll的建立
關於dll的建立,有如下幾個方面的要素是不可缺少和必須掌握的:
入口函式libmain( )
就象c程式中的winmain( )一樣,windows每次載入dll時都要執行libmain( )函式,主要用來進行一些初始化工作。通常的形式是:
int far pascal libmain(hinstance hinstance,word wdataseg,word wheapsize,lpstr lpszcmdline)
出口函式wep( )
windows從記憶體中解除安裝dll時,呼叫相應的出口函式wep( ),主要做一些清理工作,如釋放占用的記憶體資源;丟棄某些字串、點陣圖等資源;關閉開啟的檔案等等。
自定義的輸出函式
為了讓位於不同記憶體段的應用程式進行遠端呼叫,自定義的輸出函式必須定義為遠端函式(使用far關鍵字),以防使用近程指標而得到意外的結果;同時,加上pascal關鍵字可加快程式的執行速度,使**簡單高效,提高程式的執行速度。
輸出函式的引出方法
在dll的模組定義檔案中(.def)由exports語句對輸出函式逐一列出。例如:
exports wep @1 residentname
//residentname可提高dll效率和處理速度
portin @2
portout @3 //通常對所有輸出函式附加系列號
在每個輸出函式定義的說明中使用_export關鍵字來對其引出。
以上兩種方法任選其中的一種即可,不可重複。後面的兩個例項分別使用了上述兩種不同的引出方式,請留意。
2.dll的呼叫
載入dll時,windows尋找相應dll的次序如下:
.當前工作盤。
windows目錄;getwindowsdirectory( )函式可提供該目錄的路徑名。
windows系統目錄,即system子目錄;呼叫getsystemdiretory( )函式可獲得這個目錄的路徑名。
dos的path命令中羅列的所有目錄。
網路中映象的目錄列表中的全部目錄。
dll模組中輸出函式的呼叫方法:
不論使用何種語言對編譯好的dll進行呼叫時,基本上都有兩種呼叫方式,即靜態呼叫方式和動態呼叫方式。靜態呼叫方式由編譯系統完成對dll的載入和應用程式結束時dll解除安裝的編碼(如還有其它程式使用該dll,則windows對dll的應用記錄減1,直到所有相關程式都結束對該dll的使用時才釋放它),簡單實用,但不夠靈活,只能滿足一般要求。動態呼叫方式是由程式設計者用api函式載入和解除安裝dll來達到呼叫dll的目的,使用上較複雜,但能更加有效地使用記憶體,是編制大型應用程式時的重要方式。具體來說,可用如下的方法呼叫.在應用程式模組定義檔案中,用imports語句列出所要呼叫dll的函式名。如:
imports
memorydll.memoryread
memorydll.memorywrite
讓應用程式執行時與dll模組動態鏈結
先用loadlibrary載入dll,再用getprocaddress函式檢取其輸出函式的位址,獲得其指標來呼叫。如:
handle hlibrary;
farproc lpfunc;
int portvalue;
hlibrary=loadlibrary("portdll.dll");
//載入dll
if(hlibrary>31) //載入成功
三、dll應用例項源程式
1.直接記憶體訪問的dll源**
//.def檔案
library
memorydll
description 'dll for memory_read_write '
exetype windows
code
preload moveable discardable
data preload moveable single
heapsize 1024
//dll無自己的堆疊,故沒有stacksize語句
DLL程式設計技術
一 dll原理 dll dynamic link library 也就是 動態鏈結庫 是乙個可以被其它應用程式共享的程式模組,其中封裝了一些可以被共享的程式或資源。它雖然包含了可執行 卻不能單獨執行,而應由相應的應用程式直接或間接呼叫。在 windows 32 中,可以將 dll 標記為共享以導致相...
DEV Windows下DLL程式設計技術及應用
windows下dll程式設計技術及應用 一 引 言 由於windows為微機提供了前所未有的標準使用者介面 圖形處理能力和簡單靈便的操作,絕大多數程式編制人員都已轉向或正在轉向windows程式設計。在許多使用者設計的實際應用系統的程式設計任務中,常常要實現軟體對硬體資源和記憶體資源的訪問,例如埠...
Windows程式設計技術部落格二
本份部落格內容很簡單,主要研究 include語句中,引用標頭檔案時使用 和 的區別以及歸納namespace關鍵字的用法及為什麼要使用前置宣告。以下為給出的研究結果 include 引用的是編譯器的類庫路徑裡面的標頭檔案。include 引用的是你程式目錄的相對路徑中的標頭檔案.命名空間是用來阻止...