{{fbdoc item="title" value="FUNCTION Pointer"}}----
Data type that stores a pointer to a ##[[KeyPgFunction|FUNCTION]]## procedure returning a value

{{fbdoc item="syntax"}}##
	[[KeyPgDim|dim]] //variable// [[KeyPgAs|as]] [[KeyPgFunction|Function]] [[[KeyPgCdecl|CDecl]]|[[KeyPgPascal|Pascal]]|[[KeyPgStdcall|StdCall]]] [( [//parameter_list//] )] [ [[KeyPgByrefFunction|ByRef]] ] [[[KeyPgAs|As]] //return_type//] [= //initializer//]
##
{{fbdoc item="param"}}
	##//parameter_list//##: parameter[, parameter[, ...]]
	##//parameter//##: ##[[[KeyPgByref|ByRef]]|[[KeyPgByval|ByVal]]] //identifier// [[[KeyPgAs|As]] //type//] [= //default_value//]##
		##//identifier//##: the name of the variable referenced in the subroutine
		##//type//##: the type of variable
		##//default_value//##: the value of the argument if none is specified in the call
	##//return_value//##: the value returned from the function
	##//intializer//##: address of a subroutine to set as the intial value

{{fbdoc item="desc"}}
	A ##[[KeyPgFunction|Function]]## pointer is a procedure pointer that stores the memory location of compiled code that returns a value.  If no intializer is given the default initial value is zero (0).
	
	The memory address for the ##[[KeyPgFunction|Function]]## procedure can be assigned to the variable by taking the address of a subroutine with ##[[KeyPgOpProcptr|ProcPtr]]## or ##[[KeyPgOpAt|Operator @ (Address of)]]##.
	
	The procedure must match the same ##[[KeyPgFunction|Function]]## declaration as the declared ##[[KeyPgFunction|Function]]## pointer.
	
	To call the subroutine assigned, use the ##//variable//## name as if it were a normal declared ##[[KeyPgFunction|Function]]##.
	
	One of the primary uses for ##[[KeyPgFunction|Function]]## pointers is to create callback procedures:
		**""-""** A callback ##[[KeyPgFunction|Function]]## is a ##[[KeyPgFunction|Function]]## that is passed through an argument (a ##[[KeyPgFunction|Function]]## pointer) to another procedure which is expected to call back (execute) the "argument" at a convenient time.
		**""-""** If the callback ##[[KeyPgFunction|Function]]## is completely executed before the invocation returns to the caller code, then the callback process is said to be "synchronous".
		**""-""** If the invocation immediately returns to the caller code, and the callback ##[[KeyPgFunction|Function]]## and the caller's next code are running in parallel, then the callback process is said to be "asynchronous".

{{fbdoc item="ex"}}
{{fbdoc item="filename" value="examples/manual/datatype/funcptr.bas"}}%%(freebasic)
function ConcatSelf( x as string ) as string
	return x & x
end function

dim x as Function( x as string ) as string = procptr( ConcatSelf )

print x( "Hello" )
%%
{{fbdoc item="filename" value="examples/manual/datatype/funcptr2.bas"}}%%(freebasic)
Function x2 (Byval i As Integer) As Integer
  Return i * 2
End Function

Function x3 (Byval i As Integer) As Integer
  Return i * 3
End Function

Function operation (Byval i As Integer, Byval op As Function (Byval As Integer) As Integer) As Integer
  Return op(i)
End Function

Print operation(4, @x2)
Print operation(4, @x3)
%%
{{fbdoc item="filename" value="examples/manual/datatype/funcptr3.bas"}}%%(freebasic)
' Example of basic callback Function mechanism (asynchronous) to implement a key pressed event:
' (the user callback Function address cannot be modified while the event thread is running)
'   - An asynchronous thread tests the keyboard in a loop, and calls a user callback Function each time a key is pressed.
'   - The callback Function address is passed to the thread.
'   - The callback Function prints the character of the key pressed,
'       but if the key pressed is <escape> it orders the thread to finish by using the function return value.
'   - As the user callback address is passed to the thread as argument, it cannot be modified while the thread is running.


'' thread Sub definition
  Sub threadInkey (Byval p As Any Ptr)
	If p > 0 Then                                                '' test condition callback Function defined
	  Dim As Function (Byref As String) As Integer callback = p  '' convert the any ptr to a callback Function pointer
	  Do
		Dim As String s = Inkey
		If s <> "" Then                                          '' test condition key pressed
		  If callback(s) Then                                    '' test condition to finish thread
			Exit Do
		  End If
		End If
		Sleep 50, 1
	  Loop
	End If
  End Sub

'' user callback Function definition
  Function printInkey (Byref s As String) As Integer
	If Asc(s) = 27 Then                                        '' test condition key pressed = <escape>
	  Print
	  Return -1                                                '' order thread to finish
	Else
	  Print s;
	  Return 0                                                 '' order thread to continue
	End If
  End Function

'' user main code
  Dim As Any Ptr p = Threadcreate(@threadInkey, @printInkey)   '' launch the thread, passing the callback Function address
  Threadwait(p)                                                '' wait for the thread finish
%%

{{fbdoc item="diff"}}
	- New to ""FreeBASIC""

{{fbdoc item="see"}}
	- ##[[KeyPgSub|Sub]]##
	- ##[[KeyPgOpProcptr|ProcPtr]]##
	- ##[[KeyPgOpAt|Operator @ (Address of)]]##

{{fbdoc item="back" value="CatPgStdDataTypes|Standard Data Types"}}