vb内嵌汇编学习心得

经过一段时间的学习,总算把vb的函数调用,以及类方法的压栈方式弄懂了。

虽然vb可以通过类型库定义接口方法,更方便,但是直接用vb的类的方式,调用函数指针也是可以的。网上有很多方法是通过callwindowproc那个回调函来实现vb使用函数指针。不过我实现了用vb嵌汇编来实现调用函数指针。

'IVBoost类模块

Public Function UAdd(ByVal x As Long, ByVal y As Long) As Long
  '0
End Function
Public Function UDif(ByVal x As Long, ByVal y As Long) As Long
  '1
End Function

Public Function CallLongReturnLong(ByVal pFn As Long, ByVal x As Long) As Long
  '2 还可以加入更多的调用方式
End Function

‘--------------------------

'VBoostImp.cls


Private mVBoost As IVBoost
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" ( _
     ByRef Destination As Any, _
     ByRef Source As Any, _
     ByVal Length As Long)


Private ASM(300) As Long

Dim pTVable As Long
Private Sub Class_Initialize()
   Set mVBoost = New IVBoost
  
   Dim pObj As Long
   pObj = ObjPtr(mVBoost)
  
  
   CopyMemory pTVable, ByVal pObj, 4

   '-------------------
'UAdd
    ASM(0) = &H824448B
    ASM(1) = &HC244403
    ASM(2) = &H245C8B53
    ASM(3) = &H5B038914
    ASM(4) = &H10C2C033
    ASM(5) = &H90909000
    SetVTable VarPtr(ASM(0)), 0

   mov eax, [esp+8]
   Add eax, [esp+12]
   push ebx
   mov ebx, [esp+20]
   mov [ebx], eax
   pop ebx
   xor eax,eax
   ret 16
'------------------------

UDif
    ASM(6) = &H824448B
    ASM(7) = &HC24442B
    ASM(8) = &H245C8B53
    ASM(9) = &H5B038914
    ASM(10) = &H10C2C033
    ASM(11) = &H90909000
     SetVTable VarPtr(ASM(6)), 1

    mov eax, [esp+8]
    sub eax,[esp+12]
    push ebx
    mov ebx, [esp+20]
    mov [ebx], eax
    pop ebx
    xor eax,eax
    ret 16
'-----------------------------
'
' CallLongReturnLong
    ASM(12) = &H824448B
    ASM(13) = &HC2474FF
    ASM(14) = &H8B53D0FF
    ASM(15) = &H8914245C
    ASM(16) = &HC0335B03
    ASM(17) = &H900010C2
       
    SetVTable VarPtr(ASM(12)), 2
   
   mov eax,[esp+8]     把调用地址先保存到eax
   push [esp+12]       再压入参数 x
   Call eax
   push ebx
   mov ebx, [esp+20]
   mov [ebx], eax     ; 返回值
   pop ebx
   xor eax,eax
   ret 16
'--------------------------
  
End Sub

Public Property Get VBoost() As IVBoost
    Set VBoost = mVBoost
End Property


Private Sub SetVTable(ByVal fn As Long, ByVal iOrder As Long)
   
    CopyMemory ByVal (pTVable + (7 + iOrder) * 4), fn, 4
   
End Sub

Private Function pFn(ByVal x As Long) As Long
    pFn = x
End Function

'---------------------------

 

'使用

Dim VBoost As IVBoost
Dim VBoostImp As VBoostImp
Sub Main()
  Set VBoostImp = New VBoostImp
  Set VBoost = VBoostImp.VBoost
   
   
  With VBoost
  MsgBox .UAdd(3, 5)
  MsgBox .UDif(5, 3)
  MsgBox .CallLongReturnLong(AddressOf Test, 5)
  End With
 
End Sub


Private Function Test(ByVal x As Long) As Long
  MsgBox "ss"
  Test = x * 3
   
End Function

posted on 2010-04-21 22:05  杨志农  阅读(250)  评论(0)    收藏  举报

导航