微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

vb.net动态加载dll并执行dll中的某一个函数

注意:下面的Dll文件必须是用托管代码写的,否则请使用API的相应函数进行动态加载。

一、

比如我事先写了一个类,如下:

PublicClassTestClass

PublicFunctionAdd(ByValadd1AsInteger,ByValadd2AsInteger)AsInteger

Returnadd1+add2

EndFunction

EndClass

然后编译成了ClassDll.dll文件.

二、

在另一个程序中,我写入了如下代码

PublicFunctionAdd(ByValadd1AsInteger,ByValadd2AsInteger)AsInteger

DimasmAsSystem.Reflection.Assembly=System.Reflection.Assembly.LoadFile("ClassDll.dll")

DimclasstempAsType=asm.GetType("ClassDll.TestClass") '区分大小写,wenjian ming bu neng xiangtong

DimobjAsObject=asm.CreateInstance(classtemp.FullName)

Dimme_InfoAsSystem.Reflection.MethodInfo=classtemp.getmethod("Add")

Dimparamter(1)AsObject

paramter(0)=add1

paramter(1)=add2

Returnme_Info.Invoke(obj,paramter)

EndFunction

执行上面的Add函数功能和执行一中的Add函数是一样的。


当然,执行上面的函数的另一种方法是:(之前我用上面的方法反射执行一个exe文件里的函数时,总是失败,但是按照下面的方法就可以成功执行,你要是遇到问题时,不妨按照下面的方法试一试)

PublicFunctionAdd(ByValadd1AsInteger,ByValadd2AsInteger)AsInteger

DimasmAsSystem.Reflection.Assembly=System.Reflection.Assembly.LoadFile("ClassDll.dll")

DimclasstempAsType=asm.GetType("ClassDll.TestClass")

DimobjAsObject=asm.CreateInstance(classtemp.FullName)

ReturnCallByName(obj,"Add",vbMethod,add1,add2)'这里特别注意CallByName的用法

EndFunction

1、上面的System.Reflection.Assembly.LoadFile("ClassDll.dll")这一句里的ClassDll.dll是我们编译的那个dll文件。如果其不是放在程序目录下,这里必须换成ClassDll.dll的绝对路径

2、DimclasstempAsType=asm.GetType("ClassDll.TestClass")这里的ClassDll.dll.TestClass类为什么不是我们定义的那个TestClass类呢(ClassDll.dll是我们的dll名称),你自己打开那个dll文件看一下就知道答案了。即我们用的时候类的前面必须加上我们的dll的名称再加一个点,才构成我们的类。

3、paramter是我们函数要接收的参数。可以通过paramter来传递数据。

经测试,在wince下同样适用


同样,如何捕捉触发事件

classtemp.GetType().AddEventHandler(obj,AddressOfobj_Timer)

...
Subobj_Timer()
'Heretodealwiththetimereventofyourobject'sinstance.
EndSub

(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,
BindingFlags.Public |BindingFlags.CreateInstance,newobject[] { dataSource },null);

结果还不行,报同样的错误,于是只保留BindingFlags.CreateInstance继续测试,将代码调整如下:

(IDutyDao)Assembly.Load(m_path).CreateInstance(className,BindingFlags.CreateInstance,
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,方法参数);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐