使用委托解决不同系统加载程序问题
使用委托解决不同系统加载程序问题
需求
彩虹狗需要增加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 |

浙公网安备 33010602011771号