How is invoke supposed to be used in MASM if I want to call callback procedures, and want the call instruction produced to call an address stored in memory, rather than calling an immediate value address? Is it really acceptable to pass a DWORD variable name to invoke as the procedure name parameter, or will the output code actually call the data space rather than the addressed procedure? I just want to be sure about this to make sure I won't monkeywrench my computer by executing data.
In a procedure that calls a callback you only have the address to call back to so unless you want to use a macro prototype for that address, you would normally write the code manually with push / call syntax.
I imagine you are doing the callback calling procedure from amodule that does not have the actual callback procedure locally because if the callback proc is local in the module, you just write a normal prototype for it.
Here are the two macros from the masm32 macro file that may be useful to you if you want to use a prototype and invoke.
; --------------------------------------------
; the following two macros are for prototyping
; direct addresses with a known argument list.
; --------------------------------------------
SPROTO MACRO func_addr:REQ,arglist:VARARG ;; STDCALL version
LOCAL lp,var
.data?
func_addr dd ?
.const
var typedef PROTO STDCALL arglist
lp TYPEDEF PTR var
EXITM <equ <(TYPE lp) PTR func_addr>>
ENDM
CPROTO MACRO func_addr:REQ,arglist:VARARG ;; C calling version
LOCAL lp,var
.data?
func_addr dd ?
.const
var typedef PROTO C arglist
lp TYPEDEF PTR var
EXITM <equ <(TYPE lp) PTR func_addr>>
ENDM
Quote from: JFG on October 20, 2005, 12:54:54 AM
How is invoke supposed to be used in MASM if I want to call callback procedures,
Structure the code like a proc then invoke it.
EnumWindowsProc PROTO :HWND,:LPARAM ;Proto for Invoke syntax. Locate this above your code area.
invoke EnumWindows,offset EnumWindowsProc,0 ;Normal Call back
invoke EnumWindowsProc, hwnd, lParam ;Normal Call with Invoke.
EnumWindowsProc proc uses edi esi ebx hwnd:HWND, lParam:LPARAM
EnumWindowsProc endp
Regards, P1 :8)
Thanks Hutch and P1 for your answers.
What I actually want to do is change what procedures are called in my code so that in place of using doing lengthy conditional tests to pick out some procedure to run, as is done in the typical WndProc procedure, I can simply put in a call to a procedure address stored in memory, and put in code that changes which procedure address is stored there whenever necessary. I remembered just now that the file masm32\examples\EXAMPLE7\Ddtest\UNKNWN.INC has a macro (the vf macro) intended for passing an obvious indirect memory parameter to invoke for the procedure address, say as in the hypothetical code expansion
invoke [edx].IDirectDraw2Vtbl.GetCaps, pIDD2, . . .
but I figured the use of [edx] within that first parameter would make the use of a memory parameter there obvious to MASM, whereas the use of a plain variable name might not. I also didn't want to first copy the procedure address into a register and then pass a register name as a parameter to invoke because in principle I shouldn't have to do that, and because I may often want to preserve the values of all general registers other than eax, and want to not have to always add in extra code for shuffling register values in every such case. Anyway, I figured MASM should be designed to be able to identify variable names as memory parameters automatically, although I wasn't absolutely certain. (Weird issues I have with my computer and its installation of Windows make me jittery about experimenting with things like that too.) I just want to be sure then that MASM does make correct use of variable names when provided in place of procedure names, although I then wonder too how MASM responds to that on the subject of typechecking and other things concerning calling conventions, at least if the convention I am using is C or STDCALL.
P.S.: I checked the PDF version of the MASM manual to try to find answers for these questions, but Adobe Acrobat couldn't even find the text "invoke" in there. Did I maybe just do something wrong?
What your suggesting is a lot like COM. But you want a few shortcuts in the mix.
Go for it. Programming is only limited by syntax, hardware and your imagination. Most of the time it's our imagination that's the problem. So roll your own and share with us later.
Regards, P1 :8)
Ah - okay, thanks for the encouragement. But does MASM make correct use of variable names in place of procedure names with invoke, does it just generate calls to stuff in the data segment, or does it just complain that I screwed up the first parameter to invoke? I actually need to use variable names as parameters for the generated call instructions also because I want to make DLLs, and want to be able to load them at run-time, which requires the use of calls to procedures whose addresses are stored in memory. Should I just make my own macro to substitute for invoke and handle this?
What you want to do requires PROTOTYPES for your function ptrs - like this:
PR2 typedef proto :dword, :dword
PPR2 typedef ptr PR2
fp1 PPR2 ?
fp2 dd ?
dummy:
invoke fp1, 1, 2
invoke PR2 ptr fp2, 1, 2
ret
Awesome! Thanks. That's exactly what I needed to know.
JFG,
Would you please share with us, what you are trying to accomphish?
Regards, P1 :8)