How to use procedural variables

From Free Pascal wiki
Jump to: navigation, search

Copy the text below and it will demonstrate the use of procedural variables, this is a fully working program. You don't even need to understand how it works the syntax is pretty simple.


program Test;
 
{$mode objfpc}{$H+}
uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes;
 
// Make the Types the type corresponds to a function signature
type
  TFuncNoArgsString = function(): String;
  TFuncOneArgsString = function(x: string): string;
 
// Example functions
function Hello: String;
begin
  Result := 'Hello There';
end;
 
function Woah(G: String): String;
begin
  Result := 'Woah ' + G;
end;
 
// Overloaded function takes the two types of function
// pointers created above
procedure Take(f: TFuncNoArgsString); overload;
begin
  WriteLn(f());
end;
 
procedure Take(f: TFuncOneArgsString); overload;
begin
  WriteLn(f('there!!!'));
end;
 
var
  ptr: Pointer;
  List: TList;
begin
  // the "@" symbol turns the variable into a pointer.
  // This must be done in order pass a function as a 
  // paramater.  This also demonstrates that pascal
  // keeps track of the pointer type so the overloading works!
 
  Take(@Hello);
  Take(@Woah);
 
  // Now put a function in an untyped pointer
  ptr := @Hello;
  // Type the pointer and call it all at the same time
  WriteLn(TFuncNoArgsString(ptr));
  // A TList Example
  List := TList.Create;
  List.Add(@Hello);
  WriteLn(TFuncNoArgsString(List[0]));
  ReadLn;
end.