一酣溃、 動態(tài)鏈接庫概述:
什么是動態(tài)鏈接庫?DLL三個字母是Dynamic Link Library 的縮寫形式,動態(tài)鏈接庫 (DLL) 是作為共享函數庫的可執(zhí)行文件予权。動態(tài)鏈接提供了一種方法些楣,使進程可以調用不屬于其可執(zhí)行代碼的函數脂凶。函數的可執(zhí)行代碼位于一個 DLL 中,該 DLL 包含一個或多個已被編譯愁茁、鏈接并與使用它們的進程分開存儲的函數蚕钦。DLL 還有助于共享數據和資源。多個應用程序可同時訪問內存中單個 DLL 副本的內容鹅很。
和大多數程序員一樣嘶居,你一定很使用過DLL吧。也曾感受到它的帶給你程序設計和編碼上的好處吧促煮!今天這里探討一個主題:如何在C#創(chuàng)建和調用DLL(動態(tài)鏈接庫), 其實在很大意義上而講邮屁,DLL讓我更靈活的組織編寫我們的應用程序,作為軟件設計者污茵,可一個根據它來達到很高的代碼重用效果樱报。下面我來介紹一下在C#中如何創(chuàng)建和調用DLL。
二泞当、準備工作
我們需要對我們接下來要做的事情做個簡單的介紹迹蛤,在本文我們將利用C#語言創(chuàng)建一個名為 MyDLL.DLL的動態(tài)鏈接庫,在這個動態(tài)鏈接庫文件中我們將提供兩個功能一個是對兩個參數交換他們的值,另一個功能是求兩個參數的最大公約數盗飒。然后創(chuàng)建一個應用程序使用這個DLL嚷量。運行并輸出結果。
三逆趣、創(chuàng)建DLL
讓我們創(chuàng)建以下三個C#代碼文件:
1蝶溶、 MySwap.cs
using System;
namespace MyMethods {
public class SwapClass {
public static bool Swap(ref long i,ref long j) {
i = i+j;
j = i-j;
i = i-j;
return true;
}
}
}
2、MyMaxCD.cs
using System;
namespace MyMethods {
public class MaxCDClass {
public static long MaxCD(long i, long j) {
long a,b,temp;
if(i>j) {
a = i; b = j;
} else {
b = i; a = j;
}
temp = a % b;
while(temp!=0) {
a = b;
b = temp;
temp = a % b;
}
return b;
}
}
}
需要注意的是:我們在制作這兩個文件的時候可以用Visual Studio.NET或者其他的文本編輯器宣渗,就算是記事本也可以抖所。這兩個文件雖然不在同一個文件里面,但是他們是屬于同一個namespace(名稱空間)這對以后我們使用這兩個方法提供了方便痕囱。當然他們也可以屬于不同的名稱空間田轧,這是完全可以的,但只是在我們應用他們的時候就需要引用兩個不同的名稱空間鞍恢,所以作者建議還是寫在一個名稱空間下面比較好傻粘。
接下來的任務是把這兩個cs文件變成我們需要的DLL文件。
方法是這樣的:
在安裝了Microsoft.NET Framework的操作系統(tǒng)上帮掉,我們可以在Windows所在目錄下找到Microsoft.NET目錄弦悉。
在這個目錄下面提供了C#的編譯器,CSC.EXE運行:
csc /target:library /out:MyDLL.DLL MySwap.cs MyMaxCD.cs蟆炊,
完成后可在本目錄下面找到我們剛才生成的MyDLL.DLL文件/target:library 編譯器選項通知編譯器輸出 DLL 文件而不是 EXE 文件稽莉。
后跟文件名的 /out 編譯器選項用于指定 DLL 文件名。
如果/out后面不跟文件名編譯器使用第一個文件 (MySwap.cs) 作為 DLL 文件名盅称。生成的文件為MySwap.DLL文件肩祥。
OK!我們創(chuàng)建動態(tài)鏈接庫文件的任務完成了,現在是我們享受勞動成果的時候了缩膝,下面我將介紹如何使用我們所創(chuàng)建的動態(tài)鏈接庫文件混狠。
四、使用DLL
我們簡單寫一個小程序來測試一下我們剛才寫的兩個方法是否正確:
MyClient.cs代碼如下:
using System;
using MyMethods; //這里我們引用剛才定義的名稱空間疾层,如果剛才的兩個文件我們寫在兩個不同的名稱空間
class MyClient {
public static void Main(string[] args) {
if (args.Length != 2) {
Console.WriteLine("Usage: MyClient <num1><num2>");
return;
}
long num1 = long.Parse(args[0]);
long num2 = long.Parse(args[1]);
SwapClass.Swap(ref num1,ref num2); // 請注意将饺,文件開頭的 using 指令使您得以在編譯時使用未限定的類名來引用 DLL 方法
Console.WriteLine("The result of swap is num1 = {0} and num2 ={1}",num1, num2);
long maxcd = MaxCDClass.MaxCD(num1,num2);
Console.WriteLine("The MaxCD of {0} and {1} is {2}",num1, num2, maxcd); } }
若要生成可執(zhí)行文件 MyClient.exe,請使用以下命令行:
csc /out:MyClient.exe /reference:MyDLL.DLL MyClient.cs
/out 編譯器選項通知編譯器輸出 EXE 文件并且指定輸出文件名 (MyClient.exe)痛黎。
/reference 編譯器選項指定該程序所引用的 DLL 文件予弧。
五、執(zhí)行
若要運行程序湖饱,請輸入 EXE 文件的名稱掖蛤,文件名的后面跟兩個數字,例如:MyClient 123 456
六井厌、輸出
The result of swap is num1 = 456 and num2 = 123 The MaxCD of 456 and 123 is 3
七蚓庭、小結:
動態(tài)鏈接具有下列優(yōu)點:
1致讥、節(jié)省內存和減少交換操作。很多進程可以同時使用一個 DLL器赞,在內存中共享該 DLL 的一個副本垢袱。相反,對于每個用靜態(tài)鏈接庫生成的應用程序港柜,Windows 必須在內存中加載庫代碼的一個副本请契。
2、節(jié)省磁盤空間夏醉。許多應用程序可在磁盤上共享 DLL 的一個副本爽锥。相反,每個用靜態(tài)鏈接庫生成的應用程序均具有作為單獨的副本鏈接到其可執(zhí)行圖像中的庫代碼授舟。
3救恨、升級到 DLL 更為容易。DLL 中的函數更改時释树,只要函數的參數和返回值沒有更改,就不需重新編譯或重新鏈接使用它們的應用程序擎淤。相反奢啥,靜態(tài)鏈接的對象代碼要求在函數更改時重新鏈接應用程序。
4嘴拢、提供售后支持桩盲。例如,可修改顯示器驅動程序 DLL 以支持當初交付應用程序時不可用的顯示器席吴。
5赌结、支持多語言程序。只要程序遵循函數的調用約定孝冒,用不同編程語言編寫的程序就可以調用相同的 DLL 函數柬姚。程序與 DLL 函數在下列方面必須是兼容的:函數期望其參數被推送到堆棧上的順序,是函數還是應用程序負責清理堆棧庄涡,以及寄存器中是否傳遞了任何參數量承。
6、提供了擴展 MFC 庫類的機制穴店∷汉矗可以從現有 MFC 類派生類,并將它們放到 MFC 擴展 DLL 中供 MFC 應用程序使用泣洞。
7忧风、使國際版本的創(chuàng)建輕松完成。通過將資源放到 DLL 中球凰,創(chuàng)建應用程序的國際版本變得容易得多狮腿「么埃可將用于應用程序的每個語言版本的字符串放到單獨的 DLL 資源文件中,并使不同的語言版本加載合適的資源蚤霞。使用 DLL 的一個潛在缺點是應用程序不是獨立的酗失;它取決于是否存在單獨的 DLL 模塊。