加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-17 08:11:32 所属栏目:百科 来源:网络整理
导读:注意:下面的Dll文件必须是用托管代码写的,否则请使用API的相应函数进行动态加载。 一、 比如我事先写了一个类,如下: Public Class TestClass Public Function Add ( ByVal add1 AsInteger , ByVal add2 AsInteger ) AsInteger Return add1+add2 End Functi

注意:下面的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,方法参数);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读