位置:首頁 > 軟件操作教程 > 編程開發(fā) > C# > 問題詳情

C#程序嵌入DLL的調(diào)用

提問人:劉冬梅發(fā)布時間:2020-10-12
1) ldfs類的編寫:

在項目“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)裝載與卸載了。

繼續(xù)查找其他問題的答案?

相關(guān)視頻回答
回復(fù)(0)
返回頂部