Prototypes used to speed up calling Procedures
Prototypes used to speed up calling Procedures
A Nubie Question: I know how to call procedures using pointers but I have been advised that for maximum speed I should use prototypes. I don't know how to do that. Can someone point me to info on prototypes/pseudotypes in this way? Perhaps a simple program fragment that does this would be a good away to start? My reading of the PB docs that I have read has left me clueless (i am a refugee from Power Basic which doesn't have prototypes.
Thank you for any suggestions. HGC
Thank you for any suggestions. HGC
Re: Prototypes used to speed up calling Procedures
Here's a quick example.
Hope it helps.
Code: Select all
Procedure.i Function1(intParam)
Debug "Hello from 'Function1' - intParam = " + intParam
ProcedureReturn 1
EndProcedure
Procedure.i Function2(intParam)
Debug "Hello from 'Function2' - intParam = " + intParam
ProcedureReturn 2
EndProcedure
;Declare a prototype which is a template for a new kind of variable (just like .l, .i, .s etc.)
;The following line simply says : 'We are interested in calling some functions which take a single integer parameter and returns an integer'.
Prototype.i simpleProtoType(param)
;We can now declare a variable whose type matches our prototype. Just like defining any regular variable.
ptr.simpleProtoType
;Our variable 'ptr' has been declared as a pointer to a function whose prototype happens to match both functions above.
;However, this variable is currently null. Let us point it at Function1().
ptr = @Function1() ;In words : 'Assign the variable ptr the address of Function1'.
;We can now call Function1 through the 'ptr' variable.
;We see that the prototype definition requires that we pass a single integer parameter.
returnValue = ptr(10)
Debug "Our function call returned the value : " + returnValue
Debug "===="
;Let us now call Function2 through the 'ptr' variable.
;We just need to alter ptr so that it points at Function2.
ptr = @Function2()
returnValue = ptr(20)
Debug "Our function call returned the value : " + returnValue
Debug "===="
Last edited by srod on Thu Feb 20, 2014 4:59 pm, edited 1 time in total.
I may look like a mule, but I'm not a complete ass.
Re: Prototypes used to speed up calling Procedures
Code: Select all
; Callback example using prototype.
Prototype.i Fn1_CB(cb_trigger.i)
Procedure Fn1_CB(cb_trigger.i)
Debug cb_trigger
EndProcedure
Procedure Fn1(nPts.i, delay_ms.i, CB.Fn1_CB=0)
Protected.i i
For i = 1 To nPts
If CB <> 0 ; callback exists
CB(i)
EndIf
Delay(delay_ms)
Next i
EndProcedure
Fn1(32, 100, @Fn1_CB())
Fn1(32, 100);, @Fn1_CB())
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: Prototypes used to speed up calling Procedures
Here's a practical example of prototypes and pseudotypes in action. In the first snippet, we have to use the StringToBstr() procedure we created in order to pass a unicode filename to the GdipLoadImageFromFile function (if we don't have our compiler options set to unicode executable). In the days before Purebasic got pseudotypes this was always necessary:
Here is the same code but in the GdipLoadImageFromFile prototype we give the filename parameter a pseudotype of p-unicode. Now the extra procedure is not necessary any more and the code is smaller, cleaner and more self-documenting:
Code: Select all
Procedure StringToBStr (string$) ; By Zapman Inspired by Fr34k
Protected Unicode$ = Space(Len(String$)* 2 + 2)
Protected bstr_string.l
PokeS(@Unicode$, String$, -1, #PB_Unicode)
bstr_string = SysAllocString_(@Unicode$)
ProcedureReturn bstr_string
EndProcedure
Structure GdiplusStartupInput
GdiPlusVersion.l
*DebugEventCallback.Debug_Event
SuppressBackgroundThread.l
SuppressExternalCodecs.l
EndStructure
Prototype GdipLoadImageFromFile( *filename, *image )
Prototype GdiplusStartup( *token, *input, mode )
Prototype GdiplusShutdown( *token )
Prototype GdipDisposeImage( *image )
OpenLibrary(gdipluslib, "gdiplus.dll")
Global GdipLoadImageFromFile.GdipLoadImageFromFile = GetFunction(gdipluslib, "GdipLoadImageFromFile")
Global GdiplusStartup.GdiplusStartup = GetFunction( 0, "GdiplusStartup" )
Global GdiplusShutdown.GdiplusShutdown = GetFunction( 0, "GdiplusShutdown" )
Global GdipDisposeImage.GdipDisposeImage = GetFunction( 0, "GdipDisposeImage" )
input.GdiplusStartupInput
input\GdiPlusVersion = 1
GdiplusStartup( @*token, @input, #Null)
file$ = #PB_Compiler_Home + "examples\sources\data\world.png"
GdipLoadImageFromFile( StringToBStr(file$), @*image )
Debug *image ; non-zero here means it worked
If *image
GdipDisposeImage(*image)
EndIf
GdiplusShutdown(*token)
Code: Select all
Structure GdiplusStartupInput
GdiPlusVersion.l
*DebugEventCallback.Debug_Event
SuppressBackgroundThread.l
SuppressExternalCodecs.l
EndStructure
Prototype GdipLoadImageFromFile( filename.p-unicode, *image )
Prototype GdiplusStartup( *token, *input, mode )
Prototype GdiplusShutdown( *token )
Prototype GdipDisposeImage( *image )
OpenLibrary(gdipluslib, "gdiplus.dll")
Global GdipLoadImageFromFile.GdipLoadImageFromFile = GetFunction(gdipluslib, "GdipLoadImageFromFile")
Global GdiplusStartup.GdiplusStartup = GetFunction( 0, "GdiplusStartup" )
Global GdiplusShutdown.GdiplusShutdown = GetFunction( 0, "GdiplusShutdown" )
Global GdipDisposeImage.GdipDisposeImage = GetFunction( 0, "GdipDisposeImage" )
input.GdiplusStartupInput
input\GdiPlusVersion = 1
GdiplusStartup( @*token, @input, #Null)
file$ = #PB_Compiler_Home + "examples\sources\data\world.png"
GdipLoadImageFromFile( file$, @*image )
Debug *image ; non-zero here means it worked
If *image
GdipDisposeImage(*image)
EndIf
GdiplusShutdown(*token)
BERESHEIT
Re: Prototypes used to speed up calling Procedures
You should really use the "p-bstr" prototype then 

- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: Prototypes used to speed up calling Procedures


(hehe)
BERESHEIT
Re: Prototypes used to speed up calling Procedures
Wow! Thank you all. I am impressed with the speed and relevance of the answers. I am starting out with the first by "srod" who seems to have considerable experience teaching. When I can get to it, I'll post timing results. I am very pleased with these responses and am very happy to have a chance to join the PB family. Thank you all very much indeed. HGC
Re: Prototypes used to speed up calling Procedures
Very nice explanatory examples. Thank you, all.
Perhaps these could be linked to the manual; would make these functions more easily understandable.
Perhaps these could be linked to the manual; would make these functions more easily understandable.
DE AA EB
Re: Prototypes used to speed up calling Procedures
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
( The path to enlightenment and the PureBasic Survival Guide right here... )
Re: Prototypes used to speed up calling Procedures
Thanks for all the examples, guys, I've never understood them 100% (I'm slow
).
Now I have no excuse

Now I have no excuse

Win10, PB6.x, okayish CPU, onboard video card, fuzzy monitor (or is that my eyesight?)
"When the facts change, I change my mind" - John Maynard Keynes
"When the facts change, I change my mind" - John Maynard Keynes
- flaith
- Enthusiast
- Posts: 704
- Joined: Mon Apr 25, 2005 9:28 pm
- Location: $300:20 58 FC 60 - Rennes
- Contact:
Re: Prototypes used to speed up calling Procedures
http://www.youtube.com/watch?v=UKwVvSleM6wnetmaestro wrote:I was so proud of my brilliant post! Shot down in flames... I'm going to go play with spider now
(hehe)

“Fear is a reaction. Courage is a decision.” - WC
Re: Prototypes used to speed up calling Procedures
Fred, when you tell that, it means what ?Fred wrote:You should really use the "p-bstr" prototype then
That all 'p-unicode' could be change by 'p-bstr' ?
According MS here, we can use bstr type for typedef WCHAR OLECHAR.
As it's explain, unicode is different from BSTR (no prefix for example).
GdipLoadImageFromFile_() is declared like this in gdiplusflat.h file (from last SKD version).
I've readen that OLECHAR is a string of wchar_t and WCHAR is declared in WinNT.h as follows: typedef wchar_t WCHAR;GdipLoadImageFromFile(GDIPCONST WCHAR* filename, GpImage **image);
Is that right if i tell that p-unicode can be changed by p-bstr all the times ?
A+
Denis
Denis
Re: Prototypes used to speed up calling Procedures
No, you should use p-bstr only when it's really a necessity, as it does allocate and free a SYSString at every call. I think than p-unicode is enough for most of cases, unless PBSTR is specified in the API (sometimes an API can modify the string and return a new one).