FreeBASIC – gestione degli errori

La gestione degli errori è un aspetto molto importante che un programmatore deve conoscere per scrivere del codice affidabile.

Può capitare per esempio di dover aprire un file, ma, per qualche motivo, il file è stato cancellato, spostato o rinominato. In questi casi è bene prevedere un controllo per intercettare l’eventuale errore ed informare così l’utente del problema.

A tale scopo FreeBASIC mette a disposizione la funzione err che ritorna lo specifico codice di errore del problema riscontrato.

In FreeBASIC esiste una lista dei codici di errore che il programmatore può gestire.

Vediamo un semplice esempio:

dim err_code as integer

open "file.txt" for input as #1

err_code = err

select case err_code
  case 0
    close #1 'nessun errore riscontrato
  case 1
    print "Illegal function call"
  case 2
    print "File not found signal"
  case 3
    print "File I/O error"
  case 4
    print "Out of memory"
  case 5
    print "Illegal resume"
  case 6
    print "Out of bounds array access"
  case 7
    print "Null Pointer Access"
  case 8
    print "No privileges"
  case 9
    print "Interrupted signal"
  case 10
    print "Illegal instruction signal"
  case 11
    print "Floating point error signal"
  case 12
    print "Segmentation violation signal"
  case 13
    print "Termination request signal"
  case 14
    print "Abnormal termination signal"
  case 15
    print "Quit request signal"
  case 16
    print "Return without gosub"
  case 17
    print "End of file"
end select

sleep

Abbastanza semplice direi. 😉

In FreeBASIC esistono anche altre istruzioni e procedure che permettono una gestione degli errori avanzata.

A rileggerci al prossimo articolo.

FreeBASIC – libreria dinamica

A differenza della libreria statica che abbiamo visto nel precedente articolo, la libreria dinamica viene caricata soltanto quando il nostro programma è in esecuzione (runtime).

Altra importante caratteristica è che la libreria dinamica può essere condivisa (shared) tra più programmi in esecuzione.

Passiamo subito alla pratica e scriviamo quattro files.

Modulo libreria

''nome del file: funzioni_utili.bas

''funzione per il calcolo dell'area di un quadrato
public function area_quadrato(byval l as integer) _
       as integer
  return l * l
end function

Una volta salvato il file dobbiamo compilarlo specificando al compilatore FreeBASIC che vogliamo creare proprio una libreria dinamica:

fbc -dll [eventuale percorso]\funzioni_utili.bas

Se tutto è andato in porto troveremo nella stessa cartella contenente il file sorgente la nostra libreria.

Sui sistemi operativi Linux l’estensione del file sarà .so, mentre sul sistema operativo Windows l’estensione del file sarà .dll.

A questo punto il file della libreria dinamica va spostato in specifiche cartelle a seconda del sistema operativo:

  • su Linux: /usr/lib
  • su Windows: la cartella di sistema (p.e. C:\Windows\System32)

Interfaccia

Come abbiamo già fatto per rendere facilmente disponibile la libreria statica, anche per la libreria dinamica creiamo la nostra interfaccia (API) sfruttando un file di intestazione:

''nome file: funzioni_utili.bi

#inclib "funzioni_utili" ''include il modulo libreria

''dichiara la funzione
declare function area_quadrato(byval l as integer) _
        as integer

Test

Creiamo adesso due programmi sostanzialmente identici che, una volta mandati in esecuzione, condivideranno la medesima libreria dinamica.

Programma 1

''nome file: test1.bas

#include "funzioni_utili.bi" ''include l'interfaccia

dim a as integer

''stampa l'area del quadrato
do
  input "Test 1: Inserisci la lunghezza del lato: "; a
  print "L'area del quadrato vale: "; area_quadrato(a)
loop until a = 0

Programma 2

''nome file: test2.bas

#include "funzioni_utili.bi" ''include l'interfaccia

dim a as integer

''stampa l'area del quadrato
do
  input "Test 2: Inserisci la lunghezza del lato: "; a
  print "L'area del quadrato vale: "; area_quadrato(a)
loop until a = 0

Bene! Con questo articolo possiamo per ora ritenere la nostra conoscenza dell’uso delle librerie in FreeBASIC sufficiente.

Ricordiamoci però sempre di ben commentare le nostre librerie per aiutare chi volesse utilizzarle a capire velocemente come funzionano.

A rileggerci al prossimo articolo. 🙂

FreeBASIC – libreria statica

Nel precedente articolo abbiamo avuto modo di dare un primo sguardo alla teoria che riguarda le librerie.

Oggi passeremo alla pratica realizzando la nostra prima libreria statica.

Una libreria statica è un file contenente del codice compilato che svolge diversi compiti. Questo codice può essere utilizzato nel proprio progetto e quindi aggiunto staticamente durante la creazione del file eseguibile.

Facciamo quindi un semplice esempio creando una libreria che contiene un unico modulo con un’unica funzione:

Modulo libreria

''nome del file: libreria.bas

''funzione per il calcolo dell'area di un triangolo
public function area(byval b as integer, _
                     byval h as integer) as integer
  return b * h / 2
end function

A questo punto dobbiamo compilare il file specificando al compilatore FreeBASIC che vogliamo creare una libreria e non un eseguibile:

fbc -lib libreria.bas

Noteremo che nella stessa cartella del modulo compare ora il file liblibreria.a che è il file archivio contenente la nostra libreria.

Un archivio può contenere più moduli.

Interfaccia

Per facilitare l’uso della nostra libreria è bene creare una interfaccia (API) che permetta ad un qualsiasi programmatore interessato di accedere facilmente alle varie funzioni messe a disposizione.

In FreeBASIC per creare una interfaccia, non facciamo altro che scrivere un file di intestazione.

''nome del file: libreria.bi

#inclib "libreria" ''include il modulo libreria

declare function area(byval b as integer, _
                      byval h as integer) as integer

Programma

Immaginiamo ora di essere un programmatore che voglia utilizzare la funzione area della nostra libreria.

Scriviamo quindi questo semplice programma:

''nome file: test.bas

#include "libreria.bi" ''include il file di intestazione

'stampa l'area del triangolo
print "L'area del triangolo vale: "; area(4, 5)

A questo punto si compila il modulo del programma (test.bas) e si ottiene il file eseguibile che ingloba anche la libreria.

Nel prossimo articolo creeremo invece una libreria dinamica.

FreeBASIC – salvare e caricare immagini

Dopo aver imparato come creare una immagine, oggi vedremo come salvarla in un file utilizzando il formato bitmap e quindi come poterla caricare per usi successivi.

Come salvare una immagine

L’istruzione per salvare una qualsiasi immagine è la funzione bsave.

La funzione restituisce il valore 0 (zero) se il salvataggio è andato a buon fine, altrimenti viene restituito un codice di errore.

Vediamo l’uso di questa istruzione con un semplice esempio:

screen 19, 32, 1

''dimensiona la variabile per gestire il
''valore restituito dalla funzione bsave
dim risultato as long

''dimensiona la variabile di tipo puntatore
''per l'indirizzo di memoria
dim immagine1 as any ptr

''crea l'immagine
immagine1 = imagecreate(200, 200, rgb(255,0,0))
if immagine1 = 0 then
  print "Creazione dell'immagine non riuscita!"
  sleep
else
  ''disegna un cerchio verde al centro
  circle immagine1, (100, 100), 50, rgb(0,255,0)
  ''inserisce l'immagine all'interno
  ''della finestra grafica
  put(150, 150), immagine1
end if

print "Premi un tasto per salvare l'immagine."
sleep

''salva l'immagine
risultato = bsave("immagine.bmp", immagine1)
if risultato <> 0 then
  print "Salvataggio dell'immagine non riuscito!"
else
  print "L'immagine e' stata correttamente salvata."
end if

sleep

Ora, se il salvataggio è riuscito, andiamo a rinominare il file della nostra immagine modificandolo poi con un qualsiasi programma di grafica prima di provare a caricarlo.

Come caricare una immagine

L’istruzione per caricare le immagini è bload.

Aggiungiamo ora questo blocco di codice in fondo al programma che abbiamo appena provato:

print "Premi un tasto per caricare l'immagine"
print "modificata in una nuova posizione."
sleep

risultato = bload("immagine2.bmp", immagine1)
if risultato <> 0 then
  print "Caricamento dell'immagine non riuscito!"
  sleep
else
  print "L'immagine e' stata correttamente caricata."
  ''inserisce l'immagine all'interno
  ''della finestra grafica
  put(300, 50), immagine1
  print "Premi un tasto per uscire."
  sleep
  ''distrugge l'immagine per liberare la memoria
  imagedestroy immagine1
end if

Se tutto è andato a buon fine dovremmo essere riusciti a visualizzare, in una diversa posizione dello schermo, la nostra immagine modificata.

Bene. Anche per oggi possiamo ritenerci soddisfatti. Un altro piccolo passo è stato fatto nel percorso di apprendimento del FreeBASIC. 🙂

FreeBASIC – creare una immagine

Spesso può rivelarsi utile creare una immagine in memoria invece che disegnarla direttamente sullo schermo grafico.

Poi, una volta creata, sarà possibile richiamarla attraverso il suo indirizzo di memoria.

Questo procedimento, oltre a velocizzare il disegno delle immagini, rende possibile vari effetti grafici che possono migliorare l’efficacia e la qualità dei nostri programmi.

Possiamo immaginare ciascuna immagine come una tela contenuta all’interno di una cornice avente delle specifiche dimensioni (larghezza e altezza); la tela potrà essere colorata o trasparente.

Come creare una immagine

La funzione che ci permette di creare un’immagine è imagecreate disponibile in due versioni:

screen 19, 32, 1

''dimensiona due variabili di tipo puntatore
''per gli indirizzi di memoria
dim immagine1 as any ptr
dim immagine2 as any ptr

''I versione con i seguenti argomenti:
''- larghezza
''- altezza
''- colore dello sfondo
immagine1 = imagecreate(200, 200, rgb(255,0,0))
if immagine1 = 0 then
  print "Creazione dell'immagine 1 non riuscita!"
  sleep
else
  ''disegna un cerchio verde al centro
  circle immagine1, (100, 100), 50, rgb(0,255,0)
  ''inserisce l'immagine all'interno
  ''della finestra grafica
  put(150, 150), immagine1
  ''distrugge l'immagine per liberare la memoria
  imagedestroy immagine1
end if

''II versione con l'aggiunta di un quarto argomento:
''- profondità di colore
immagine2 =imagecreate(200, 200, rgb(0,255,0), 32)
if immagine2 = 0 then
  print "Creazione dell'immagine 2 non riuscita!"
  sleep
else
  ''disegna un cerchio rosso al centro
  circle immagine2, (100, 100), 50, rgb(255,0,0)
  ''inserisce l'immagine all'interno
  ''della finestra grafica
  put(300, 300), immagine2
  ''distrugge l'immagine per liberare la memoria
  imagedestroy immagine2
end if

sleep

Note sulla istruzione imagecreate

  • L’istruzione va utilizzata soltanto dopo aver definito la modalità grafica: e quindi sia la risoluzione dello schermo che la risoluzione grafica.
  • Se il colore dello sfondo non viene specificato, il valore predefinito sarà trasparente e quindi in pratica sarà visibile il colore di sfondo della finestra grafica.
  • Se l’istruzione dovesse fallire, viene restituito il valore null (0), altrimenti viene restituito l’indirizzo di memoria dell’immagine.

Per fare le cose per bene, occorre anche ricordarsi di distruggere le immagini create in modo tale da liberare la memoria. Per farlo si utilizza l’istruzione imagedestroy.

Bene. Per oggi possiamo fermarci qui. Nel prossimo articolo impareremo a salvare e caricare le immagini.

FreeBASIC – il cerchio

Nei precedenti articoli abbiamo lavorato con il punto e la linea, oggi lavoreremo con il cerchio e l’ellisse.

Istruzione circle

L’istruzione che impareremo ad usare per disegnare cerchi ed ellissi è circle.

Come abbiamo fatto per il punto e per la linea, anche in questo caso scriveremo un semplice programma per esplorare le potenzialità di questa istruzione.

''definizione della costante pi greco
const pi = 3.14159

screen 19, 32
color(rgb(0,0,0),rgb(255,255,255))
cls

''cerchio color giallo con centro identificato
''da coordinate assolute
circle (100,100), 50, rgb(255,255,0)

''cerchio color ciano con centro identificato
''da coordinate relative
circle step (50,50), 50, rgb(0,255,255)

''arco color magenta con estremi a 0 rad e pi/2 rad
circle step (50,50), 50, rgb(255,0,255), 0, (90*pi/180)

''ellisse color rosso
circle step (50,50), 50, rgb(255,0,0),,,0.5

''ellisse color verde piena
circle step (50,50), 50, rgb(0,255,0),,,0.25,F

sleep

Con l’aiuto dei commenti il codice è abbastanza intuitivo.

Gli unici aspetti dell’istruzione che meritano qualche nota in più sono:

  • i due argomenti che gestiscono gli estremi dell’arco che devono essere espressi in radianti (più sotto un utile schema per la conversione gradi/radianti);
  • l’argomento che gestisce la proporzione tra l’altezza e la larghezza dell’ellisse (nel caso del cerchio varrà ovviamente 1.0).

Schema per la conversione gradi/radianti

Degree-Radian Conversion it.svg

Fonte: Wikipedia (pubblico dominio, collegamento al file)

Bene. Per oggi ci fermiamo qui. 🙂