Lazarus Student Tutorial

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 11

https://lazarus-freepascal.blogspot.com/2017/09/tutorial-lazarus-en-espanol-pdf.

html
https://wiki.freepascal.org/Lazarus_Documentation
https://doc.lagout.org/programmation/Pascal/Free%20Pascal%20User%27s%20Gui
de.pdf
https://forum.lazarus.freepascal.org/index.php?topic=47096.0
https://lazarus-ccr.sourceforge.io/fpcdoc/prog/prog.html

Functions:

Functions work the same way as procedures, but they always return a single value
to the main program through its own name:

function Name (parameter_list) : return_type;


Functions are called in the main program by using them in expressions:

a := Name (5) + 3;
If your function has no argument, be careful not to use the name of the function on
the right side of any equation inside the function. That is:

function Name : integer;


begin
Name := 2;
Name := Name + 1
end.
is a no-no. Instead of returning the value 3, as might be expected, this sets up an
infinite recursive loop in certain language modes (e.g. {$MODE DELPHI} or {$MODE
TP}; other modes require brackets for function call even if the brackets are empty
due to no parameters being required for the particular function). Name will call
Name, which will call Name, which will call Name, etc.

The return value is set by assigning a value to the function identifier.

Name := 5;
It is generally bad programming form to make use of VAR parameters in functions --
functions should return only one value. You certainly don't want the sin function to
change your pi radians to 0 radians because they're equivalent -- you just want the
answer 0.

Making libraries

https://lazarus-ccr.sourceforge.io/fpcdoc/prog/progse29.html#x190-1950007.2

7.2 Making libraries


Free Pascal supports making shared or static libraries in a straightforward and easy
manner. If you want to make static libraries for other Free Pascal programmers, you
just need to provide a command line switch. To make shared libraries, refer to the
chapter 12, page 633. If you want C programmers to be able to use your code as
well, you will need to adapt your code a little. This process is described first.
7.2.1 Exporting functions
7.2.2 Exporting variables
7.2.3 Compiling libraries
7.2.4 Unit searching strategy

Programming shared libraries:

Chapter 12
Programming shared libraries
12.1 Introduction
12.2 Creating a library
12.3 Using a library in a pascal program
12.4 Using a pascal library from a C program
12.5 Some Windows issues
[next] [prev] [prev-tail] [front] [up]

12.2 Creating a library


Creation of libraries is supported in any mode of the Free Pascal compiler, but it may
be that the arguments or return values differ if the library is compiled in 2 different
modes. E.g. if your function expects an Integer argument, then the library will expect
different integer sizes if you compile it in Delphi mode or in TP mode.
A library can be created just as a program, only it uses the library keyword, and it
has an exports section. The following listing demonstrates a simple library:
Listing: progex/subs.pp

{
Example library
}
library subs;

function SubStr(CString: PChar;FromPos,ToPos: Longint): PChar; cdecl;

var
Length: Integer;

begin
Length := StrLen(CString);
SubStr := CString + Length;
if (FromPos > 0) and (ToPos >= FromPos) then
begin
if Length >= FromPos then
SubStr := CString + FromPos - 1;
if Length > ToPos then
CString[ToPos] := #0;
end;
end;

exports
SubStr;

end.
Creating library example

uses dynlibs;

var
MyLibC: TLibHandle;
MyProc: TMyProc;
begin
MyLibC := LoadLibrary('libc.' + SharedSuffix);
if MyLibC = 0 then Exit;
MyProc := TMyProc(GetProcedureAddress(MyLibC, 'getpt');
if MyProc = nil then Exit;
end;
Pseoudocode for using a function, taking parameters:

uses ...dynlibs...

procedure UseDLL;
type
TMyFunc=function (aInt:Integer; aStr: string):String; StdCall;
var
MyLibC: TLibHandle= dynlibs.NilHandle;
MyFunc: TMyFunc;
FuncResult: string;
begin
MyLibC := LoadLibrary('libc.' + SharedSuffix);
if MyLibC = dynlibs.NilHandle then Exit; //DLL was not loaded successfully
MyFunc:= TMyFunc(GetProcedureAddress(MyLibC, 'MyFunc');
FuncResult:= MyFunc (5,'Test'); //Executes the function
if MyLibC <> DynLibs.NilHandle then if FreeLibrary(MyLibC) then MyLibC:=
DynLibs.NilHandle; //Unload the lib, if already loaded
end;

uses dynlibs;

var
MyLibC: TLibHandle;
MyProc: TMyProc;
begin
MyLibC := LoadLibrary('libc.' + SharedSuffix);
if MyLibC = 0 then Exit;
MyProc := TMyProc(GetProcedureAddress(MyLibC, 'getpt');
if MyProc = nil then Exit;
end;

Pseoudocode for using a function, taking parameters:

uses ...dynlibs...

procedure UseDLL;
type
TMyFunc=function (aInt:Integer; aStr: string):String; StdCall;
var
MyLibC: TLibHandle= dynlibs.NilHandle;
MyFunc: TMyFunc;
FuncResult: string;
begin
MyLibC := LoadLibrary('libc.' + SharedSuffix);
if MyLibC = dynlibs.NilHandle then Exit; //DLL was not loaded
successfully
MyFunc:= TMyFunc(GetProcedureAddress(MyLibC, 'MyFunc');
FuncResult:= MyFunc (5,'Test'); //Executes the function
if MyLibC <> DynLibs.NilHandle then if FreeLibrary(MyLibC) then MyLibC:=
DynLibs.NilHandle; //Unload the lib, if already loaded
end;
12.2 Creating a library
Creation of libraries is supported in any mode of the Free Pascal compiler, but it
may be that the arguments or return values differ if the library is compiled in 2
different modes. E.g. if your function expects an Integer argument, then the
library will expect different integer sizes if you compile it in Delphi mode or in TP
mode.

A library can be created just as a program, only it uses the library keyword,
and it has an exports section. The following listing demonstrates a simple
library:

Listing: progex/subs.pp

{
Example library
}
library subs;

function SubStr(CString: PChar;FromPos,ToPos: Longint):


PChar; cdecl;

var
Length: Integer;

begin
Length := StrLen(CString);
SubStr := CString + Length;
if (FromPos > 0) and (ToPos >= FromPos) then
begin
if Length >= FromPos then
SubStr := CString + FromPos;
if Length > ToPos then
CString[ToPos+1] := #0;
end;
end;

exports
SubStr;

end.

The function SubStr does not have to be declared in the library file itself. It can
also be declared in the interface section of a unit that is used by the library.

Compilation of this source will result in the creation of a library


called libsubs.dylib on MacOS, libsubs.so on other UNIX systems,
or subs.dll on WINDOWS or OS/2. The compiler will take care of any additional
linking that is required to create a shared library.

The library exports one function: SubStr. The case is important. The case as it
appears in the exports clause is used to export the function.

If you want your library to be called from programs compiled with other
compilers, it is important to specify the correct calling convention for the exported
functions. Since the generated programs by other compilers do not know about the
Free Pascal calling conventions, your functions would be called incorrectly,
resulting in a corrupted stack.

On WINDOWS, most libraries use the stdcall convention, so it may be better to


use that one if your library is to be used on WINDOWS systems. On
most UNIX systems, the C calling convention is used, therefore
the cdecl modifier should be used in that case.
See also

http://cc.etsii.ull.es/ftp/antiguo/MTDPRG1/freepascal/manual/prog/node13.html

You might also like