It's a generic question, but how do I create a function in MASM that accepts a function pointer?
I have searched a few books (including Irvine and Pirogov) and couldn't find anything on this.
I have searched the forum and found some discussions on how to call a function using a pointer, but not how to write a function that expects a function pointer - like you do in C.
Thanks in advance.
FuncProc PROTO :DWORD
Func PROTO
;
.CODE
FuncProc PROC lpfnProc:DWORD
call dword ptr lpfnProc
ret
FuncProc ENDP
Func PROC
ret
Func ENDP
;to call it
INVOKE FuncProc,Func
Perhaps more explains ( a sample for example) could be useful.
Here is some samples
Monproc proc
...
Monproc endp
.data
pointer dd Monproc ;put the adress of Monproc in pointer
.code
invoke afunction,parm1,Monproc ;pass the adress of Monproc to afunction
If you want to use INVOKE, a typedef is needed:
MYMSG typedef proto hWnd:HWND,psz1:PCHAR,psz2:PCHAR,flg:DWORD
PMYMSG typedef ptr MYMSG
myMsg proc hWnd:HWND,psz1:PCHAR,psz2:PCHAR,flg:DWORD
invoke MessageBox,hWnd,psz1,psz2,flg
ret
myMsg endp
xyz proc pFnc:PMYMSG
invoke pFnc,0,0,0,0
; or: invoke PMYMSG ptr ...,0,0,0,0
ret
xyz endp
...
invoke xyz,myMsg
;I translate this from syslinux
; It has a table function defined like this
PMVect struc
nSize dword 0
_lmalloc dd 0
_lfree dd 0
_open_file dd 0
_read_file dd 0
_close_file dd 0
_opendir dd 0
_readdir dd 0
_closedir dd 0
_idle dd 0
_reset_idle dd 0
_chdir dd 0
_getcwd dd 0
_jiffies dd 0
_ms_timer dd 0
PMVect ends
PM_VEC_TABLE dd OFFSET nSize dword, OFFSET _lmalloc,OFFSET_lfree, OFFSET_open_file dd 0 ... etc. OFFSET _ms_time
GetPMVector proc
mov eax,offset _ms_time
ret
GetPMVector endp
OpenFile proc lpPointer:dword,lpName:dword
mov ecx,lpPointer
push lpname
call [ecx].PMVect._open_file
add esp,4
ret
OpenFile endp
;Here is how you used it
Invoke GetVectoreTable
invoke OpenFile,eax,CADD("MyFile.txt")
its pretty easy, get the ADDRESS of the function and pass it to another function as a single DWORD value.
Now with the receiving function, it needs to be able to call the passed function, the low level way to do this is to use the PUSH / CALL technique common in MASM programming.
Pseudo code.
called_function proc fptr:DWORD, any other args etc ...
LOCAL retval :DWORD
push arg3 ; args required by the passed function
puch arg2
push arg1
call fptr
mov retval, eax ; get its return value
; any other code
ret
called_function endp