您的位置:首页 > 其它

使用委托解决不同系统加载程序问题

2009-11-17 08:59 363 查看
使用委托解决不同系统加载程序问题

需求

彩虹狗需要增加64位驱动,解决方法可以不修改程序,在做安装程序的时候使用不同的版本,只需要文件名相同就可以。

而我之前看了些有关委托方法的使用,就想尝试一下在不调整其它配置的情况下,支持不同环境的调用。

分析

原先的代码中,对外提供的公开方法是直接调用32位DLL中的函数,如下

Friend Class Dog

……

Declare Function Check_Dog Lib "htbdog.dll" Alias "Check_Dog" (ByVal DogCascade As Integer, ByVal DogPassword As Integer, ByRef RetCode As Integer) As Integer

Declare Function Read_Dog Lib "htbdog.dll" Alias "Read_Dog" (ByVal DogCascade As Integer, ByVal DogPassword As Integer, ByVal DogAddr As Integer, ByVal DogBytes As Integer, ByVal DogData() As Byte, ByRef RetCode As Integer) As Integer

Declare Function Write_Dog Lib "htbdog.dll" Alias "Write_Dog" (ByVal DogCascade As Integer, ByVal DogPassword As Integer, ByVal DogAddr As Integer, ByVal DogBytes As Integer, ByVal DogData() As Byte, ByRef RetCode As Integer) As Integer

……

End Class

而新增64位DLL中的函数,其名称、形参、返回值是与32位DLL完全相同的,只是文件名不同(32位为htbdog.dll,64位为htbdog64.dll)

本想使用反射的方法进行动态调用,但是考虑到反射调用的性能比较差,所以尝试使用委托方法来实现

解决思路如下:

1. 为32位与64位的DLL分别声明调用函数,函数名称以32、64结尾来区别,例如:

Declare Function Check_Dog32 Lib "htbdog.dll" Alias "Check_Dog" (ByVal DogCascade As Integer, ByVal DogPassword As Integer, ByRef RetCode As Integer) As Integer

Declare Function Check_Dog64 Lib "htbdog64.dll" Alias "Check_Dog" (ByVal DogCascade As Integer, ByVal DogPassword As Integer, ByRef RetCode As Integer) As Integer

2. 声明委托方法,形参与各个DLL中函数一致

Private Delegate Function gateCheck_Dog(ByVal DogCascade As Integer, ByVal DogPassword As Integer, ByRef RetCode As Integer) As Integer

Private entCheck_Dog As gateCheck_Dog

3. 在实例化Dog对象时,根据当前系统的不同,实例化具体委托对象的方法。例如

Public Sub New()

'IntPtr.Size = 4 32 位系统,使用htbdog.dll

If IntPtr.Size = 4 Then

entCheck_Dog = New dCheck_Dog(AddressOf Check_Dog32)

 ……

Else

entCheck_Dog = New dCheck_Dog(AddressOf Check_Dog64)

 ……

End If

End Sub

4. 对外公开方法调用委托对象实现

Public Function Check_Dog(ByVal DogCascade As Integer, ByVal DogPassword As Integer, ByRef RetCode As Integer) As Integer

Return entCheck_Dog.Invoke(DogCascade, DogPassword, RetCode)

End Function

这样调整之后,对外部公开的方法调用没有发生变化,而只是在内部进行了处理,相比反射的动态调用性能好一些

示例代码

Friend Class Dog

……

'来自32位DLL的函数声明

#Region "硬件狗操作函数(32位系统)"

Declare Function Check_Dog32 Lib "htbdog.dll" Alias "Check_Dog" (ByVal DogCascade As Integer, ByVal DogPassword As Integer, ByRef RetCode As Integer) As Integer

Declare Function Read_Dog32 Lib "htbdog.dll" Alias "Read_Dog" (ByVal DogCascade As Integer, ByVal DogPassword As Integer, ByVal DogAddr As Integer, ByVal DogBytes As Integer, ByVal DogData() As Byte, ByRef RetCode As Integer) As Integer

Declare Function Write_Dog32 Lib "htbdog.dll" Alias "Write_Dog" (ByVal DogCascade As Integer, ByVal DogPassword As Integer, ByVal DogAddr As Integer, ByVal DogBytes As Integer, ByVal DogData() As Byte, ByRef RetCode As Integer) As Integer

……

#End Region

'来自64位DLL的函数声明

#Region "硬件狗操作函数(64位系统)"

Declare Function Check_Dog64 Lib "htbdog64.dll" Alias "Check_Dog" (ByVal DogCascade As Integer, ByVal DogPassword As Integer, ByRef RetCode As Integer) As Integer

Declare Function Read_Dog64 Lib "htbdog64.dll" Alias "Read_Dog" (ByVal DogCascade As Integer, ByVal DogPassword As Integer, ByVal DogAddr As Integer, ByVal DogBytes As Integer, ByVal DogData() As Byte, ByRef RetCode As Integer) As Integer

Declare Function Write_Dog64 Lib "htbdog64.dll" Alias "Write_Dog" (ByVal DogCascade As Integer, ByVal DogPassword As Integer, ByVal DogAddr As Integer, ByVal DogBytes As Integer, ByVal DogData() As Byte, ByRef RetCode As Integer) As Integer

……

#End Region

'委托函数声明与DLL函数的参数、返回类型一致

Private Delegate Function gateCheck_Dog(ByVal DogCascade As Integer, ByVal DogPassword As Integer, ByRef RetCode As Integer) As Integer

Private Delegate Function gateRead_Dog(ByVal DogCascade As Integer, ByVal DogPassword As Integer, ByVal DogAddr As Integer, ByVal DogBytes As Integer, ByVal DogData() As Byte, ByRef RetCode As Integer) As Integer

Private Delegate Function gateWrite_Dog(ByVal DogCascade As Integer, ByVal DogPassword As Integer, ByVal DogAddr As Integer, ByVal DogBytes As Integer, ByVal DogData() As Byte, ByRef RetCode As Integer) As Integer

……

'声明委托对象为指定的委托函数

Private entCheck_Dog As gateCheck_Dog

Private entRead_Dog As gateRead_Dog

Private entWrite_Dog As gateWrite_Dog

……

'实例化时,根据当前系统的不同,实例化委托对象的对应函数

Public Sub New()

'IntPtr.Size = 4 32 位系统,使用htbdog.dll

If IntPtr.Size = 4 Then

entCheck_Dog = New dCheck_Dog(AddressOf Check_Dog32)

entRead_Dog = New dRead_Dog(AddressOf Read_Dog32)

entWrite_Dog = New dWrite_Dog(AddressOf Write_Dog32)

 ……

Else

entCheck_Dog = New dCheck_Dog(AddressOf Check_Dog64)

entRead_Dog = New dRead_Dog(AddressOf Read_Dog64)

entWrite_Dog = New dWrite_Dog(AddressOf Write_Dog64)

 ……

End If

End Sub

'公开函数调用通过委托对象进行调用

Public Function Check_Dog(ByVal DogCascade As Integer, ByVal DogPassword As Integer, ByRef RetCode As Integer) As Integer

Return entCheck_Dog.Invoke(DogCascade, DogPassword, RetCode)

End Function

Public Function Read_Dog(ByVal DogCascade As Integer, ByVal DogPassword As Integer, ByVal DogAddr As Integer, ByVal DogBytes As Integer, ByVal DogData() As Byte, ByRef RetCode As Integer) As Integer

Return entRead_Dog(DogCascade, DogPassword, DogAddr, DogBytes, DogData, RetCode)

End Function

Public Function Write_Dog(ByVal DogCascade As Integer, ByVal DogPassword As Integer, ByVal DogAddr As Integer, ByVal DogBytes As Integer, ByVal DogData() As Byte, ByRef RetCode As Integer) As Integer

Return entWrite_Dog(DogCascade, DogPassword, DogAddr, DogBytes, DogData, RetCode)

End Function

End Class

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐