vb.net動態載入dll並執行dll中的某一個函式
注意:下面的Dll檔案必須是用託管程式碼寫的,否則請使用API的相應函式進行動態載入。
一、
比如我事先寫了一個類,如下:
Public Class TestClass
Public Function Add(ByVal add1 As Integer, ByVal add2 As Integer) As Integer
Return add1 + add2
End Function
End Class
然後編譯成了ClassDll.dll檔案.
二、
在另一個程式中,我寫入瞭如下程式碼
Public Function Add(ByVal add1 As Integer
Dim asm As System.Reflection.Assembly = System.Reflection.Assembly.LoadFile("ClassDll.dll")
Dim classtemp As Type = asm.GetType("ClassDll.TestClass") '區分大小寫,wenjian ming bu neng xiangtong
Dim obj As Object = asm.CreateInstance(classtemp.FullName)
Dim me_Info As System.Reflection.MethodInfo = classtemp.GetMethod("Add")
Dim paramter(1) As Object
paramter(0) = add1
paramter(1) = add2
Return me_Info.Invoke(obj, paramter)
End Function
執行上面的Add函式其功能和執行一中的Add函式是一樣的。
當然,執行上面的函式的另一種方法是:(之前我用上面的方法反射執行一個exe檔案裡的函式時,總是失敗,但是按照下面的方法就可以成功執行,你要是遇到問題時,不妨按照下面的方法試一試)
Public Function Add(ByVal add1 As Integer, ByVal add2 As Integer) As Integer
Dim asm As System.Reflection.Assembly = System.Reflection.Assembly.LoadFile("ClassDll.dll")
Dim classtemp As Type = asm.GetType("ClassDll.TestClass")
Dim obj As Object = asm.CreateInstance(classtemp.FullName)
Return CallByName(obj, "Add", vbMethod,add1,add2)'這裡特別注意CallByName的用法
End Function
1、上面的 System.Reflection.Assembly.LoadFile("ClassDll.dll")這一句裡的ClassDll.dll是我們編譯的那個dll檔案。如果其不是放在程式目錄下,這裡必須換成ClassDll.dll的絕對路徑。
2、Dim classtemp As Type = asm.GetType("ClassDll.TestClass")這裡的ClassDll.dll.TestClass類為什麼不是我們定義的那個TestClass類呢(ClassDll.dll是我們的dll名稱),你自己開啟那個dll檔案看一下就知道答案了。即我們用的時候類的前面必須加上我們的dll的名稱再加一個點,才構成我們的類。
3、paramter是我們函式要接收的引數。可以通過paramter來傳遞資料。
經測試,在wince下同樣適用
同樣,如何捕捉觸發事件
classtemp.GetType().AddEventHandler(obj, AddressOf obj_Timer)
...
Sub obj_Timer()
' Here to deal with the timer event of your object's instance.
End Sub
(IDutyDao)Assembly.Load(m_path).CreateInstance(className); 上述程式碼表示使用預設無引數的建構函式建立一個物件例項,如果要在建立物件例項的時候呼叫有引數的建構函式該如何實現呢?
考幫助文件使用過載的CreateInstance方法來建立物件例項的程式碼如下:
(IDutyDao)Assembly.Load(m_path).CreateInstance(className,false,BindingFlags.Public,null,
newobject[] { dataSource },null,null);
結果不行,報錯:
System.MissingMethodException: System.MissingMethodException: 未找到型別
“ToTop.CSIM.DAL.DaoSqlServerImpl.DutyDaoImpl”上的建構函式。
經過多次嘗試和網上搜索均未果,找到的都是一些提出遇到了同樣問題卻沒有解決辦法的帖子,最後靜下心來詳細檢視該過載方法的幫助文件,
發現第三個引數有文章,將程式碼調整如下:
(IDutyDao)Assembly.Load(m_path).CreateInstance(className,false,
BindingFlags.Public |BindingFlags.CreateInstance,null,newobject[] { dataSource },null,null);
結果還不行,報同樣的錯誤,於是只保留BindingFlags.CreateInstance繼續測試,將程式碼調整如下:
(IDutyDao)Assembly.Load(m_path).CreateInstance(className,false,BindingFlags.CreateInstance,
null,newobject[] { dataSource },null,null);
上述程式碼測試通過!
上述方法中的具體引數說明可參閱幫助文件。
在使用.NET建立的程式或元件時,元資料(metadata)和程式碼(code)都儲存於“自成一體”的單元中,這個單元稱為裝配件。我們可以在程式執行期間訪問這些資訊。
在System.Reflection中有這樣一個class————Assembly,我們可以通過它來載入一個裝配件。方法如下:
Assembly assm=Assembly.LoadFrom(fileName);
其中filename是要載入的裝配件的檔名稱(帶路徑)。
接下來,我們就可以通過使用System.Reflection內提供的Info classes來獲取裝配件中的資訊了。首先讓我們看一下這些Info classes:
MethodInfo 獲取某個“成員函式”的資訊,並提供對此“成員函式”元資料的訪問。
ParameterInfo 獲取某個“引數”的資訊,並提供對此“引數”元資料的訪問。
Constructorinfo 獲取某個“建構函式”的資訊,並提供對此“建構函式”元資料的訪問。
PropertyInfo 獲取某個“屬性”的資訊,並提供對此“屬性”元資料的訪問。
FieldInfo 獲取某個“資料成員”的資訊,並提供對此“資料成員”元資料的訪問。
EventInfo 獲取某個“事件”的資訊,並提供對此“事件”元資料的訪問。
上面列出的這些classes(除ParameterInfo外)的訪問操作,要通過一個Type物件來完成。比如我們要獲得一個裝配件的“成員函式”就要這樣做:
System.Reflection.Assembly ass=System.Reflection.Assembly.LoadFrom(fileName);
Type[] tp=ass.GetTypes();
System.Reflection.MethodInfo[] mi=tp[0].GetMethods();
使用同樣的方法我們還可以得到其它的資訊,如下:
獲得“建構函式”資訊:System.Reflection.ConstructorInfo[] ci=tp[0].GetConstructors();
獲得“屬性”資訊:System.Reflection.PropertyInfo[] pi=tp[0].GetProperties();
獲得“資料成員”資訊:System.Reflection.FieldInfo[] fi=tp[0].GetFields();
獲得“事件”資訊:System.Reflection.EventInfo[] ei=tp[0].GetEvents();
此外,我們可以通過ParameterInfo類來獲取“成員函式”和“建構函式”的引數資訊,如下:
獲取“成員函式”的引數資訊:System.Reflection.ParameterInfo[] pi=mi[0].GetParameters();
獲取“建構函式”的引數資訊:System.Reflection.ParameterInfo[] pi=ci[0].GetParameters();
ParameterInfo類有兩個重要的屬性:Name和ParameterType。通過它們我們可以得到“引數”的名稱和資料型別。
由於.NET將class的資訊以“元資料”的形式封裝在程式或是元件中,又提供了一系列可以獲取“元資料”的方法,所以我們可以程式執行期間來動態的訪問這些資訊。
以下摘自百度:http://zhidao.baidu.com/question/294391411.html
個人膚淺理解,反射實際上就是得到程式集中的屬性和方法.
實現步驟:
1,匯入using System.Reflection;
2,Assembly.Load("程式集")載入程式集,返回型別是一個Assembly
3, foreach (Type type in assembly.GetTypes())
{
string t = type.Name;
}
得到程式集中所有類的名稱
4,Type type = assembly.GetType("程式集.類名");獲取當前類的型別
5,Activator.CreateInstance(type); 建立此型別例項
6,MethodInfo mInfo = type.GetMethod("方法名");獲取當前方法
7,mInfo.Invoke(null,方法引數);