Prototypes make me sick

Just starting out? Need help? Post your questions and find answers here.
mubinaktan
User
User
Posts: 19
Joined: Mon Oct 08, 2007 11:25 am

Prototypes make me sick

Post by mubinaktan »

Can you please "point" me a good tutor about prototypes?

I am trying to learn from PB's chm help file and "PB Survival Guide" but the subject seems so hard. I need extra support...
Thalius
Enthusiast
Enthusiast
Posts: 711
Joined: Thu Jul 17, 2003 4:15 pm
Contact:

Post by Thalius »

Quickie Example :)

Code: Select all


; Define a testfunction
Procedure Popup(String.s)
  MessageRequester("Hi",String.s)
EndProcedure

; We Create a Prototype for our Function which basically creates a Structure that we can assign 
; to a variable (which remains local if not specified otherwise). This can be handy to have functions
; only local.  
; 
; With Pseudotypes we could pass for example our String always as ASCII 
; to the function, even when compile din unicode mode. Useful for old 
; codes or dlls which dont accept unicode strings.
; Pseudotype:
; PrototypeC.l _MyPopupPrototype(String.p-ascii) 
;
PrototypeC.l _MyPopupPrototype(String.s)

; Define the new Prototype command ( basically a variable ) & assign our ptototype structure to it 
; and give it the function adress from our custom function
; via:
; foo._myprototype = GetFunction(#Library,"name_of_function")
; you can also give it the adress of a library function to simply wrap a dll command.
MyNewPopup._MyPopupPrototype = @Popup()


;Call our new prototype function  
MyNewPopup("Hello World!")
Thalius
"In 3D there is never enough Time to do Things right,
but there's always enough Time to make them *look* right."
"psssst! i steal signatures... don't tell anyone! ;)"
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

I don't understand the concept of prototypes at all. In your example above,
what's the purpose of wrapping the MessageRequester command like that?
In which situations is it advantageous to use prototypes? Do they enable
functionality that standard commands don't?
Last edited by PB on Thu Nov 22, 2007 9:01 pm, edited 1 time in total.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

1. Understand the CallFunctionFast() system.
2. Read it:
A prototype is a type that you give a variable. That variable can then be used as a pointer (to a procedure), but instead of using CallFunctionFast() on it, you can use it directly.
3. Try it:

Code: Select all

Procedure TestProc(A.s)
  MessageRequester("", A)
EndProcedure

FunctionPointer = @TestProc() ; Or Use GetFunction() if the function is in a dll
CallFunctionFast(FunctionPointer, "Function pointer")

Prototype ProtoTestProc(A.s)

Proto.ProtoTestProc
Proto = FunctionPointer
CallFunctionFast(Proto, "Proto 1")
Proto("Simpler syntax")
So a prototyped variable is just a normal function pointer that you call without CallFunctionFast(). The prototype is the type of the variable, and it used for checking that you use the correct parameters.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

PB wrote:In your example above, what's the purpose of wrapping the MessageRequester command like that?
It's just because you can't the address of a standard function, and needs the address to use a prototype...
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Prototypes are also far more flexible than using CallFunctionFast() etc. because it can deal with different kinds of parameters and return types; floats, quads etc. Something which CallFunctionFast() cannot handle.

Prototypes are very very useful and very simple once you get the hang of them.
I may look like a mule, but I'm not a complete ass.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Look at it like this. Here is a structure which serves as a template for data to be organized in a certain way:

Code: Select all

Structure stuff
  number.l
  float.f
  byte.b
EndStructure
Now when you want to create a variable of this type, you might do:

var.stuff

and var is a pointer to a memory block set aside and organized according to the stuff structure. You know exactly what you're dealing with and where to find each member. It's a concept you're familiar with as an experienced PB programmer, so you understand it well by now.

A prototype is the same concept applied to procedures. You do something like:

Prototype.q action(number.l, float.f, byte.b)

and you've created a template for a procedure that takes in a long, a float and a byte and returns a quad.

Now you do:

MyProc.action = @SomeProc()

and you've created a more talented cousin of CallFunctionFast which is able to verify and correctly handle the input and return types of the procedure according to the features described in the prototype. It's just CallFunctionFast done in a more organized and professional way.
BERESHEIT
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Post by Psychophanta »

Nice explanation the Trond's one.
However the netmaestro's one is awesome, good "maestro" :wink:
Another short example using Import and Pseudotypes (short examples help to understand better, at least to me :wink: )

Code: Select all

Import "User32.lib"
  MsgB(Window.l,Body.p-unicode,Title.p-unicode,Flags.l=0) As "_MessageBoxW@16"
EndImport
Prototype.l Myfunctiontype(a.l,b.p-unicode,c.p-unicode,d.l=0); <- i like to use a,b,c,d, ... for the parameters when defining a prototype, i think it helps to understand the concept better because we are defining just a template.
*MsgeBox.Myfunctiontype=@MsgB(); <- i like to use '*' because it is indeed a pointer.
*MsgeBox(0,"Hello","World")
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
mubinaktan
User
User
Posts: 19
Joined: Mon Oct 08, 2007 11:25 am

Thanks to this excellent forum

Post by mubinaktan »

netmaestro wrote:A prototype is the same concept applied to procedures. You do something like:

Prototype.q action(number.l, float.f, byte.b)

and you've created a template for a procedure that takes in a long, a float and a byte and returns a quad.

Now you do:

MyProc.action = @SomeProc()

and you've created a more talented cousin of CallFunctionFast which is able to verify and correctly handle the input and return types of the procedure according to the features described in the prototype. It's just CallFunctionFast done in a more organized and professional way.
Perfect explanation.

.
Post Reply