Oxygen Basic
Programming => Example Code => General => Topic started by: Charles Pegge on May 10, 2011, 11:01:29 AM
-
The function below shows techniques for handling unfixed amounts of parameters when using the stdcall calling convention.
This level of flexibility is occasionally necessary when making interfaces for interpreters.
'-----------------------------------------------------
function callflex(long fun, long count) as long export
'=====================================================
'
'THIS PROTOCOL FOR STDCALL AND A VARIABLE NUMBER OF PARAMS
'IF DOUBLES ARE BEING PASSED BYVAL THEN ADD 1 EXTRA COUNT FOR EACH DOUBLE
'
'ACCESSING THE PARAMETERS
'------------------------
'
long param at & fun
'
'indexbase 1
'param[1]==fun
'param[2]==count
'param[3]... the rest of the params passed on the stack
'
'
if fun<=0 then return 0
'
'GET THE ADDRESS OF THE FUNCTION STORED IN THE ARRAY 'MAP'
'---------------------------------------------------------
'
sys f
f=map[fun]
'
'PASS ALL THE PARAMS FORWARD TO FUNCTION F
'-----------------------------------------
'
mov ecx,count
mov edx,ecx
add edx,7 'items on already stack: eip/ebp/edi/esi/ebx/fun/count
shl edx,2 'scale 4
add edx,ebp 'base ebp
(
dec ecx 'downcount params
jl exit
sub edx,4 'param address
push [edx] 'push param
repeat
)
call f 'call mapped function
'
'CLEAN UP THE STACK AND RETURN
'-----------------------------
'
mov edx,count 'to clean stack
add edx,2 'for fun and count params
shl edx,2 'scale 4
mov esp,ebp 'restore stack pointer (dump locals)
pop ebp 'restore regs ...
pop edi '
pop esi '
pop ebx '
pop ecx 'get return address
add esp,edx 'disallocate params
jmp ecx 'jump to return address
'
end function
Charles
-
Sorry to ask probably a simple question, but is this like having optional parameters?
function testOpt( float x, float y, float z, float r, float g, float b) where x, y, z are required, but the r, g, b are optional?
-
This is different from 'optional' parameters Kent.
Procedures specifying optional parameters require placeholder nulls to be pushed onto the stack wherever the parameters are not provided by the caller.
But in this case the number of parameters provided is undetermined at compile time. The second param 'count' is there to say how many dwords are used for the remaining parameters, (and these have to be cleared from the stack before returning). The first parameter 'fun' is used as an index to a table of proc addresses. So this procedure can be used as a portal to access more conventional procedures.
Charles