How to create Arguments like CallFunctionFast
Re: How to create Arguments like CallFunctionFast
As far as I know you can't.
PureBasic has no support for a rest operator (...)
PureBasic has no support for a rest operator (...)
Re: How to create Arguments like CallFunctionFast
there is no native way in PB like in Java or C.
However you can make a little workaround like an array, list or structured memory. At the moment I have not PB to test, but something like this should work (array)
However you can make a little workaround like an array, list or structured memory. At the moment I have not PB to test, but something like this should work (array)
Code: Select all
procedure bla(array intArray.i(1))
for a=0 to arraysize(intArray())
debug intArray(a)
next
endprocedure
pb 5.11
Re: How to create Arguments like CallFunctionFast
or you set it to max parameters with
or use a structured pointer
But in all facts, you have to know, how many params the procedure max have.
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
Re: How to create Arguments like CallFunctionFast
I'm not sure if this code will help you but
Best regards.
Guimauve
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)
Guimauve
Re: How to create Arguments like CallFunctionFast
I personally haven't a clue what you're asking.. are you asking what the API alternative to CallFunctionFast is?
So for instance: CallFunctionFast is CallFunction_(...)?
In the land of C++, you declare a function as you would a Prototype in PureBasic, and you then assign a pointer to that declaration, creating a definition.. this is the definition that is called.
I would imagine in PureBasic, the CallFunctionFast(...) is not just a wrapper to an API call, but a function that takes the arguments into account, so that it can put the required data into the stack for the called function to query.
So for instance: CallFunctionFast is CallFunction_(...)?
In the land of C++, you declare a function as you would a Prototype in PureBasic, and you then assign a pointer to that declaration, creating a definition.. this is the definition that is called.
I would imagine in PureBasic, the CallFunctionFast(...) is not just a wrapper to an API call, but a function that takes the arguments into account, so that it can put the required data into the stack for the called function to query.
Thanks!
-
- Addict
- Posts: 1675
- Joined: Sun Dec 12, 2010 12:36 am
- Location: Somewhere in the midwest
- Contact:
Re: How to create Arguments like CallFunctionFast
I could be wrong but I think this is what he is asking...
He wants to write a function, that can take an indeterminate amount of Parameters..
i.e it could be Foo(bar, tastes, good) or Foo(bar, junk) etc..
And I think he was using CallFunctionFast to try and illustrate what he was asking for.
i.e You call a function from a DLL/Library using CallFunctionFast, but how does it handle the parameters?? But I think he misunderstands if this is what he is asking, because the function being called is responsible for its parameters and what it expects, not CallFunctionFast itself... Or I could be a little off base too, as I have never used CFF before and have little to no experience with Imports, Prototypes, loading external libraries, etc...
He wants to write a function, that can take an indeterminate amount of Parameters..
i.e it could be Foo(bar, tastes, good) or Foo(bar, junk) etc..
And I think he was using CallFunctionFast to try and illustrate what he was asking for.
i.e You call a function from a DLL/Library using CallFunctionFast, but how does it handle the parameters?? But I think he misunderstands if this is what he is asking, because the function being called is responsible for its parameters and what it expects, not CallFunctionFast itself... Or I could be a little off base too, as I have never used CFF before and have little to no experience with Imports, Prototypes, loading external libraries, etc...
Re: How to create Arguments like CallFunctionFast
May be the use of prototypes here can help:
http://www.purebasic.fr/english/viewtop ... =Prototype
Cheers!
http://www.purebasic.fr/english/viewtop ... =Prototype
Cheers!
Re: How to create Arguments like CallFunctionFast
I don't understand why you are not simply using the Import statement. 

- Psychophanta
- Always Here
- Posts: 5153
- Joined: Wed Jun 11, 2003 9:33 pm
- Location: Anare
- Contact:
Re: How to create Arguments like CallFunctionFast
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)
So , well, as i stated, you alreade can retrieve the amount the stack pointer ('esp' in x86) by calling one time to the function. After this retrieving you can call again with the parameters, but now you know the amount of bytes these parameters must have.
Following your example here it is the way to know the amout of bytes the parameters should fit:
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"
- the function will must be runned one time with random parameters.
- Psychophanta
- Always Here
- Posts: 5153
- Joined: Wed Jun 11, 2003 9:33 pm
- Location: Anare
- Contact:
Re: How to create Arguments like CallFunctionFast
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?
-
- Addict
- Posts: 1675
- Joined: Sun Dec 12, 2010 12:36 am
- Location: Somewhere in the midwest
- Contact:
Re: How to create Arguments like CallFunctionFast
Think of it like this... Before the Age of the Internet, etc..
You have a new job delivering pizza. You have to go to an address in a part of town you've never been. You don't know if you have to turn left on this street, right on the next street, or maybe its another left? You won't know until you see the street sign.
You have a new job delivering pizza. You have to go to an address in a part of town you've never been. You don't know if you have to turn left on this street, right on the next street, or maybe its another left? You won't know until you see the street sign.
- Psychophanta
- Always Here
- Posts: 5153
- Joined: Wed Jun 11, 2003 9:33 pm
- Location: Anare
- Contact:
Re: How to create Arguments like CallFunctionFast
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.![]()
But a fornext loop probably do nothing with the 'esp', so if oyu take care with other commands inside the loop, that way could be done in general.
- Psychophanta
- Always Here
- Posts: 5153
- Joined: Wed Jun 11, 2003 9:33 pm
- Location: Anare
- Contact:
Re: How to create Arguments like CallFunctionFast
I hope this can be useful
You can also deal it with linked list instead of Array.
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
- Psychophanta
- Always Here
- Posts: 5153
- Joined: Wed Jun 11, 2003 9:33 pm
- Location: Anare
- Contact:
Re: How to create Arguments like CallFunctionFast
Functions which return a not float dot value the returned values usually is stored in the 'eax' register:
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())