I was making some project with asm to use in my vb, one of the main problems is the comunication betwheen vb and asm.
Everyone explains how to call an exported asm function of you dll, so you can comunicate from vb to your dll, but how to comunicate back to your vb code from asm, lets say that your asm code is waiting some event and then it is catched, how to pass this event to the vb.
you may think you could have some function like isThereAnEvent, and polling all the time with vb, but i dont find it very cool to do something like that.

however, here is the example of full comunication betwheen languages. last sentence, sorry my english, but is understandable, isnt it?


vb source code

create a class named class1 with this code
Event m()
Event M2(ByVal j As Long, ByVal r As Long)
Event m3()
Event m4()
Event m5(ByVal j As Long, ByVal k As Long, ByVal l As Long, ByVal m As Long, ByVal n As Long, ByVal o As Long)
Event m6(ByVal j As Long)



create a form with 2 buttons with this code

Private WithEvents miobj As Class1
Private Declare Function SomeFunc Lib "thepath\EventRaiser.dll" (ByRef X As Object) As Long
Private Declare Function SomeOther Lib "thepath\EventRaiser.dll" (ByVal X As Object) As Long

Private Sub cmdCommand1_Click()
    Call SomeFunc(miobj)
End Sub

Private Sub cmdCommand2_Click()
    Call SomeOther(miobj)
End Sub

Private Sub Form_Load()
    Set miobj = New Class1
End Sub

Private Sub miobj_m()
    MsgBox "Event N? 1 Raised"
End Sub

Private Sub miobj_m5(ByVal j As Long, ByVal k As Long, ByVal l As Long, ByVal m As Long, ByVal n As Long, ByVal o As Long)
    MsgBox "Event N? 5 Raised, parameters: " & j & "-" & k & "-" & l & "-" & m & "-" & n & "-" & o & "-"
End Sub

Private Sub miobj_m6(ByVal j As Long)
    MsgBox "Event 6 Raised, parameter:" & j
End Sub


and the asm code of the dll is this:


.data
hInstance dd 0
hDllVbVm dd 0
pRaiseEvent dd 0

.code
DllEntry proc hInst:HINSTANCE, reason:DWORD, reserver1:DWORD
LOCAL hList:DWORD

.if reason == DLL_PROCESS_ATTACH
push hInst
pop hInstance
invoke LoadLibrary,SADD("msvbvm60")
mov hDllVbVm,eax
invoke GetProcAddress,hDllVbVm,SADD("__vbaRaiseEvent")
mov pRaiseEvent,eax
.elseif reason == DLL_PROCESS_DETACH
.endif
mov eax,TRUE
ret

DllEntry endp

CallEvent proc c pObj:DWORD,nEvent:DWORD,nParam:DWORD,args:VARARG

push esi
lea esi,args
mov ecx,nParam;numero de parametros
;lea esi,;esi = apunta al ultimo
xor edx,edx
.while edx!=ecx
push dword ptr
sub esp,12
mov dword ptr,3
.if edx==1
mov dword ptr,012h;en el anteultimo siempre va esto
.endif
inc edx
;lea esi,;-4 = bytes para cambiar de parametro en la pila
lea esi,
.endw
.if nParam
add esp,4
.endif
push nParam
push nEvent
push pObj
call pRaiseEvent
mov ecx,nParam
lea esp,
.if nParam
mov ecx,nParam
lea esp,;applying the formula
lea esp,
.endif
pop esi
ret

CallEvent ENDP

SomeFunc proc obj:DWORD
LOCAL buffer[1024]:BYTE
mov eax,obj
;add eax,12*4
.if pRaiseEvent

;Raising an Object Event With no Parameters (the hard way)
pushd 0 ;0 = N? of parameters of the events
push 1 ;1 = Event Number
mov ecx, ;the object pointer (is a byref field, just a double referenciated pointer, byval are single referenciated)
push ecx ;pass it
call pRaiseEvent
add esp,3*4 ;Stack clean

;Raising an Event with 6 parameters
pushd 1 ;Parameter 6
sub esp,12 ;uve to leave 3 dwords up of the parameter, (i dont know why, dont ask me, i just debug it)
mov dword ptr,3  ;uve to put a 3 at 3 dwords distance from the parameter

pushd 2 ;Parameter 5
sub esp,12 ;same here
mov dword ptr,3 ;the 3
mov dword ptr,012h;the parameter N? (total param num - 1) or the 5 in this case
;Have to mark that is the penultimate parameter

pushd 3 ;parametro 4
sub esp,12
mov dword ptr,3

pushd 4 ;parametro 3
sub esp,12
mov dword ptr,3

pushd 5 ;parametro 2
sub esp,12
mov dword ptr,3

pushd 6 ;First parameter
sub esp,8 ;only this is not equal to the rest
mov dword ptr,3 ;the 3 still 3 dword away fromthe parameter

push 6 ;Parameter Amount
push 5 ;Event Number
mov eax,obj ;reference to the pointer of the object
mov ecx, ;the pointer of the object
push ecx;p objeto ;pushing it
call pRaiseEvent
add esp,3*4+6*16-4  ;Cleaning the stack, follow this formula:
;formula: 3*4 + ( ParamAmount*16 - 4 )
;include the parentesis only when there r parameters
;kind of stupid comment

;now whe know how to do it, just make a function, i made mine, i think work good
;calling event n?5 with 6 parameters, easy way
mov eax,obj
mov ecx,
invoke CallEvent,ecx,5,6,1,2,3,4,5,6
;raising event n? 1 with 0 parameters
mov eax,obj
mov ecx,
invoke CallEvent,ecx,1,0
;raising event n?6 with 1 parameter
mov eax,obj
mov ecx,
invoke CallEvent,ecx,6,1,9
.endif
ret

SomeFunc endp

SomeOther proc Obj:DWORD;testing with byval

invoke CallEvent,Obj,1,0
ret

SomeOther endp



that was all. Im pretty sure that anyone that program in vb and asm understand what you can do with this would be happy to have this code. ill make some applications with this and submit later. ill attach the projects of vb and asm so u can test it
Attachments:
Posted on 2007-05-22 11:07:39 by mauricioprado
mauricioprado,

Very cool mate. I personally don't use/like VB, but I do know a few people that will find this example useful. I'll be sure to pass it along. Nice work :thumbsup:
Posted on 2007-05-22 13:31:36 by Synfire

mauricioprado,

Very cool mate. I personally don't use/like VB, but I do know a few people that will find this example useful. I'll be sure to pass it along. Nice work :thumbsup:

thanks... i hope your friends find it usefull
Posted on 2007-05-24 07:33:14 by mauricioprado
Hi mauricioprado,

first once the concept is very nice, but it is hardly useful. He is fix bind to VB6 and other language is not supported. The code has some strange sections, like these for example:

.if nParam
      add esp,4
.endif

or these
mov ecx,nParam
lea esp,
.if nParam
      mov ecx,nParam
      lea esp,;applying the formula
      lea esp,
.endif

Your Stack is not correct, the VARIANTs are shifted by 4 bytes.

When you will write Code for VB5/6, then use COM. VB5/6 is the COM Language and you can fully interact via COM with VB. A very nice work for you too help write COM in MASM is OA32. -> http://objasm32.tripod.com/ You can find many sample in the package, e.g. OCX_LED.

Greats
Obi
Posted on 2007-05-25 12:29:56 by Obivan
i debug it, im pretty sure call is successfull, stack its ok i think
Posted on 2007-05-26 03:48:11 by mauricioprado
Hi,

now the Stackframe is correct:

CallEvent proc c pObj:DWORD,nEvent:DWORD,nParam:DWORD,args:VARARG
push esi
lea esi, args
mov ecx, nParam;numero de parametros

xor edx,edx
.while edx != ecx
sub esp, 16 ;<- 16 Bytes (sizeof(VARIANT))
mov word ptr , VT_I4 ;<- the VARIANT Type
mov eax, dword ptr
mov dword ptr , eax ;<- the VARIANT Value
.if edx == 1
mov dword ptr,012h;en el anteultimo siempre va esto
.endif
inc edx
add esi, sizeof(DWORD)
.endw

push ecx ;<-nParam
push nEvent
push pObj
call pRaiseEvent

mov ecx, nParam
lea esp,
.if ecx
lea esp,
lea esp,
.endif

pop esi
ret
CallEvent ENDP


Greats
Obi
Posted on 2007-05-27 04:22:28 by Obivan