Re: How to create Arguments like CallFunctionFast
Posted: Mon Dec 05, 2011 10:19 am
As far as I know you can't.
PureBasic has no support for a rest operator (...)
PureBasic has no support for a rest operator (...)
http://www.purebasic.com
https://www.purebasic.fr/english/
Code: Select all
procedure bla(array intArray.i(1))
for a=0 to arraysize(intArray())
debug intArray(a)
next
endprocedure
Code: Select all
Procedure CF(a=0,b=0,c=0,d=0.........)
Code: Select all
Structure myparamlist
param1.i
param2.i
...
EndStructure
Procedure CF(*pointer.myparamlist)
Debug *pointer\param1
EndProcedure
Code: Select all
Procedure MyProcAlpha()
Debug #PI
EndProcedure
Procedure MyProcBeta(a.f)
Debug a * #PI
EndProcedure
Procedure MyProcGamma(a.f, b.f)
Debug a + b
EndProcedure
Procedure MyProcZeta(a.f, b.f, c.f)
Debug a + b + c
EndProcedure
Procedure Call(ParamCount, func, Param00.f = 0.0, Param01.f = 0.0, Param02.f = 0.0)
Select ParamCount
Case 0
CallFunctionFast(func)
Case 1
CallFunctionFast(func, Param00)
Case 2
CallFunctionFast(func, Param00, Param01)
Case 3
CallFunctionFast(func, Param00, Param01, Param02)
EndSelect
EndProcedure
VarB.f = 1.5
VarC.f = 2.5
VarD.f = 3.5
Call(0, @MyProcAlpha())
Call(1, @MyProcBeta(), VarB)
Call(2, @MyProcGamma(), VarB, VarC)
Call(3, @MyProcZeta(), VarB, VarC, VarD)
You can know how the function modifies the stack pointer, but i don't know how to know what is the type (size) of each function parameter, i mean if a function modifies the esp value in 8 bytes, then you can know the function uses 2 long values as parameters, or also it could be 8 byte values, or 2 word values and 1 long value, etc.Louise wrote:![]()
![]()
![]()
![]()
I could write this code. Please help me to optimize my code.
Code: Select all
ProcedureDll OpenLib(Dll.s) If Dll ProcedureReturn LoadLibrary_(@Dll) EndIf EndProcedure ProcedureDll OpenFunc(ID,Func.s) If ID ProcedureReturn GetProcAddress_(ID,@Func) EndIf EndProcedure ProcedureDll FreeLib(ID) FreeLibrary_(ID) EndProcedure lib = OpenLib("User32.dll") func = OpenFunc(lib,"SetCursorPos") PUSH 100 PUSH 100 CALL func FreeLib(lib)
Code: Select all
ProcedureDLL OpenLib(Dll.s)
If Dll
ProcedureReturn LoadLibrary_(@Dll)
EndIf
EndProcedure
ProcedureDLL OpenFunc(ID,Func.s)
If ID
ProcedureReturn GetProcAddress_(ID,@Func)
EndIf
EndProcedure
ProcedureDLL FreeLib(ID)
FreeLibrary_(ID)
EndProcedure
lib = OpenLib("User32.dll")
func = OpenFunc(lib,"SetCursorPos")
espdiff.l
!mov dword[v_espdiff],esp
!;PUSH 100 100
!CALL dword[v_func]
!sub dword[v_espdiff],esp
!add esp,dword[v_espdiff]; <- leaves the esp just like it was before the calling
FreeLib(lib)
Debug "parameters should fit "+Str(-espdiff)+" bytes"
I think, however, if you don't know about the parameter requirements of the function you wanna call, then you don't know what is the function you are calling to, and so then you don't know what are you doing. Do you?Louise wrote:Ie there's no way that this problem be solved?
asm PUSH inside a PB loop is dangerous, because nobody knows what the hell does a pb loop with the stak pointer.Louise wrote:I wrote this code, please look and say your opinions.![]()
Code: Select all
If OpenLibrary(0,"user32.dll")
hFunc = GetFunction(0,"MessageBoxA")
If hFunc
Dim arg.l(3)
size.l= ArraySize(arg())
arg(0) = #Null
arg(1) = @"title"
arg(2) = @"caption"
arg(3) = 0
!mov ecx,dword[v_size]
!@@:mov eax,dword[a_arg]
!push dword[eax+ecx*4]
!dec ecx
!jnl @r
!call dword[v_hFunc]
EndIf
CloseLibrary(0)
EndIf
Code: Select all
Procedure.i CallFast(lib$,Function$,Array Args.l(1))
If OpenLibrary(0,lib$)
Protected size.l=ArraySize(Args()),res.i
Protected hFunc.l=GetFunction(0,Function$)
If hFunc
!mov eax,dword[p.v_hFunc]
!mov ecx,dword[p.v_size]
!mov edi,dword[p.a_Args]
!mov edi,dword[edi]
!@@:push dword[edi+ecx*4]
!dec ecx
!jnl @r
!call eax
!mov dword[p.v_res],eax; <- in functions commonly there is in 'eax' register where the returned not float value is stored
EndIf
CloseLibrary(0)
EndIf
ProcedureReturn res
EndProcedure
Dim arg.l(3)
arg(0) = #Null
arg(1) = @"title"
arg(2) = @"caption"
arg(3) = 0
Debug CallFast("user32.dll","MessageBoxA",arg())