C#程序嵌入DLL的調(diào)用
在項(xiàng)目“Tzb”中新建一個(gè)名為ldfs的類(lèi),意為“l(fā)oad dll from resource”,請(qǐng)注意,在這個(gè)類(lèi)中“resource”不只是嵌入在EXE程序中的資源,它也可以是硬盤(pán)上任意一個(gè)DLL文件,這是因?yàn)閘dfs的類(lèi)中的方法LoadDll有些特別,就是先從程序的內(nèi)嵌的資源中查找需加載的DLL,如果找不到,就查找硬盤(pán)上的。
首先導(dǎo)入所需的命名空間:
using System.IO; // 對(duì)文件的讀寫(xiě)需要用到此命名空間
using System.Reflection; // 使用 Assembly 類(lèi)需用此命名空間
using System.Reflection.Emit; // 使用 ILGenerator 需用此命名空間
聲明一靜態(tài)變量MyAssembly:
// 記錄要導(dǎo)入的程序集
static Assembly MyAssembly;
添加LoadDll方法:
private byte[] LoadDll(string lpFileName)
{
Assembly NowAssembly = Assembly.GetEntryAssembly();
Stream fs=null;
try
{// 嘗試讀取資源中的 DLL
fs = NowAssembly.GetManifestResourceStream(NowAssembly.GetName().Name+"."+lpFileName);
}
finally
{// 如果資源沒(méi)有所需的 DLL ,就查看硬盤(pán)上有沒(méi)有,有的話就讀取
if (fs==null&&!File.Exists(lpFileName)) throw(new Exception(" 找不到文件 :"+lpFileName));
else if(fs==null&&File.Exists(lpFileName))
{
FileStream Fs = new FileStream(lpFileName, FileMode.Open);
fs=(Stream)Fs;
}
}
byte[] buffer = new byte[(int) fs.Length];
fs.Read(buffer, 0, buffer.Length);
fs.Close();
return buffer; // 以 byte[] 返回讀到的 DLL
}
添加UnLoadDll方法來(lái)卸載DLL:
public void UnLoadDll()
{// 使 MyAssembly 指空
MyAssembly=null;
}
添加Invoke方法來(lái)進(jìn)行對(duì)DLL中方法的調(diào)用,其原理大體上和“Form1.cs”中的方法Invoke相同,不過(guò)這里用的是“Assembly.Load”,而且用了靜態(tài)變量MyAssembly來(lái)保存已加載的DLL,如果已加載的話就不再加載,如果還沒(méi)加載或者已加載的不同現(xiàn)在要加載的DLL就進(jìn)行加載,其代碼如下所示:
public object Invoke(string lpFileName,string Namespace,string ClassName,string lpProcName,object[] ObjArray_Parameter)
{
try
{// 判斷 MyAssembly 是否為空或 MyAssembly 的命名空間不等于要調(diào)用方法的命名空間,如果條件為真,就用 Assembly.Load 加載所需 DLL 作為程序集
if(MyAssembly==null||MyAssembly.GetName().Name!=Namespace)
MyAssembly=Assembly.Load(LoadDll(lpFileName));
Type[] type=MyAssembly.GetTypes();
foreach(Type t in type)
{
if(t.Namespace==Namespace&&t.Name==ClassName)
{
MethodInfo m=t.GetMethod(lpProcName);
if(m!=null)
{// 調(diào)用并返回
object o=Activator.CreateInstance(t);
return m.Invoke(o,ObjArray_Parameter);
}
else
System.Windows.Forms.MessageBox.Show(" 裝載出錯(cuò) !");
}
}
}
catch(System.NullReferenceException e)
{
System.Windows.Forms.MessageBox.Show(e.Message);
}
return (object)0;
}
2) ldfs類(lèi)的使用:
1. 把CsCount.dll作為“嵌入的資源”添加到項(xiàng)目“Tzb”中。
2. 向“Form1”窗體中添加兩個(gè)按鈕,Name和Text屬性分別為“B7”、“l(fā)dfs.Invoke調(diào)用count”;“B8”、“UnLoadDll”,并將它們調(diào)整到適當(dāng)大小和位置。
3. 打開(kāi)“Form1.cs”代碼視圖,添加一個(gè)ldfs實(shí)例:
// 添加一個(gè) ldfs 實(shí)例 tmp
private ldfs tmp=new ldfs();
4. 在“Form1.cs[設(shè)計(jì)]”視圖中雙擊按鈕B7,在“B1_Click”方法體內(nèi)添加如下代碼:
// 調(diào)用 count(0), 并使用期提示框顯示其返回值
MessageBox.Show(" 這是您第 "+tmp.Invoke("CsCount.dll","CsCount","Class1","count",new object[]{(int)0}).ToString()+" 次點(diǎn)擊此按鈕。 "," 挑戰(zhàn)杯 ");
5. 在“Form1.cs[設(shè)計(jì)]”視圖中雙擊按鈕B7,在“B1_Click”方法體內(nèi)添加如下代碼:
// 卸載 DLL
tmp.UnLoadDll();
6. “F5”運(yùn)行該程序,并先點(diǎn)擊按鈕B7三次,接著點(diǎn)擊按鈕B8,最后再點(diǎn)擊按鈕B7,此時(shí)發(fā)現(xiàn)又開(kāi)始重新計(jì)數(shù)了,情況和“dld類(lèi)的使用”類(lèi)似,也就是也實(shí)現(xiàn)了DLL的動(dòng)態(tài)裝載與卸載了。
點(diǎn)擊加載更多評(píng)論>>