C#程序嵌入DLL的調(diào)用
在項目“Tzb”中新建一個名為ldfs的類,意為“l(fā)oad dll from resource”,請注意,在這個類中“resource”不只是嵌入在EXE程序中的資源,它也可以是硬盤上任意一個DLL文件,這是因為ldfs的類中的方法LoadDll有些特別,就是先從程序的內(nèi)嵌的資源中查找需加載的DLL,如果找不到,就查找硬盤上的。
首先導(dǎo)入所需的命名空間:
using System.IO; // 對文件的讀寫需要用到此命名空間
using System.Reflection; // 使用 Assembly 類需用此命名空間
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
{// 如果資源沒有所需的 DLL ,就查看硬盤上有沒有,有的話就讀取
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方法來卸載DLL:
public void UnLoadDll()
{// 使 MyAssembly 指空
MyAssembly=null;
}
添加Invoke方法來進(jìn)行對DLL中方法的調(diào)用,其原理大體上和“Form1.cs”中的方法Invoke相同,不過這里用的是“Assembly.Load”,而且用了靜態(tài)變量MyAssembly來保存已加載的DLL,如果已加載的話就不再加載,如果還沒加載或者已加載的不同現(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(" 裝載出錯 !");
}
}
}
catch(System.NullReferenceException e)
{
System.Windows.Forms.MessageBox.Show(e.Message);
}
return (object)0;
}
2) ldfs類的使用:
1. 把CsCount.dll作為“嵌入的資源”添加到項目“Tzb”中。
2. 向“Form1”窗體中添加兩個按鈕,Name和Text屬性分別為“B7”、“l(fā)dfs.Invoke調(diào)用count”;“B8”、“UnLoadDll”,并將它們調(diào)整到適當(dāng)大小和位置。
3. 打開“Form1.cs”代碼視圖,添加一個ldfs實例:
// 添加一個 ldfs 實例 tmp
private ldfs tmp=new ldfs();
4. 在“Form1.cs[設(shè)計]”視圖中雙擊按鈕B7,在“B1_Click”方法體內(nèi)添加如下代碼:
// 調(diào)用 count(0), 并使用期提示框顯示其返回值
MessageBox.Show(" 這是您第 "+tmp.Invoke("CsCount.dll","CsCount","Class1","count",new object[]{(int)0}).ToString()+" 次點擊此按鈕。 "," 挑戰(zhàn)杯 ");
5. 在“Form1.cs[設(shè)計]”視圖中雙擊按鈕B7,在“B1_Click”方法體內(nèi)添加如下代碼:
// 卸載 DLL
tmp.UnLoadDll();
6. “F5”運行該程序,并先點擊按鈕B7三次,接著點擊按鈕B8,最后再點擊按鈕B7,此時發(fā)現(xiàn)又開始重新計數(shù)了,情況和“dld類的使用”類似,也就是也實現(xiàn)了DLL的動態(tài)裝載與卸載了。
點擊加載更多評論>>