Da Gambas-it.org - Wikipedia.
|
|
Riga 1: |
Riga 1: |
− | ===Introduzione===
| + | Thess,Sorry about that rotten meal! And the meakrt! That photo is outstandin, though. I love masks, and I find this image very engaging. Your story reminds me of the James Joyce short story "Araby." Thanks for stopping by this a.m. |
− | Gambas consente di utilizzare potenzialità e capacità di sistemi esterni mediante il richiamo di loro funzioni. A volte infatti può capitare nella programmazione la necessità di utilizzare potenzialità che Gambas da solo non può offrire{[[#Note|1]]}. L'istruzione che Gambas pone a disposizione del programmatore per richiamare tali funzioni esterne è: '''Extern'''.
| |
− | | |
− | Per il richiamo di funzioni esterne è necessario conoscere in particolare tre elementi:
| |
− | * il ''quid'', ossia il ''cosa fare'', ''cosa ottenere'';
| |
− | * la funzione esterna che ci consente di realizzare quel ''quid'';
| |
− | * la libreria nella quale è contenuta la funzione da richiamare.
| |
− | | |
− | Se quel che si vuole ottenere è possibile solamente attraverso l'uso di una funzione esterna a Gambas, bisognerà individuare la specifica funzione che consente di realizzare il nostro obiettivo. La funzione esterna, utile allo scopo del programma, dovrà essere richiamata dal nostro programma Gambas. Poiché tale funzione esterna è scritta in C, bisognerà interpretare il significato e tradurla in forma comprensibile da Gambas. Inoltre, poiché essa è appunto ''esterna'' a Gambas, bisognerà conoscere il ''luogo'' ove essa si trova. Il ''luogo'' che contiene la funzione esterna è la "''Libreria''"; ed anzi una specifica libreria, la quale, pertanto, andrà dichiarata in anticipo rispetto alla funzione. Le librerie, contenenti funzioni ''esterne'' a Gambas, richiamabili da Gambas, sono quelle con estensione '''''.so''''' . E' opportuno, quando possibile, indicare anche il numero della versione della Libreria. Inoltre, se la libreria si trova in una cartella diversa da quella dedicata alle librerie (/lib/), sarà necessario specificare anche il percorso.
| |
− | | |
− | Possiamo, dunque, dire che è un po' come se ''Extern'' annunciasse: « ''Farò in modo che il programma utilizzi questa funzione "xxxx(yyy)", la quale non appartiene alle risorse di Gambas, ma si trova in questa libreria: zzzz.so (oppure già precedentemente dichiarata).'' ».
| |
− | | |
− | | |
− | ====Identificazione e dichiarazione della Libreria contenente la Funzione esterna====
| |
− | La Libreria, contenente la funzione esterna da richiamare, può essere dichiarata separatamente, e prima della dichiarazione ''Extern'':
| |
− | | |
− | Library "libreria_esterna:num_vers"
| |
− |
| |
− | Extern......
| |
− | | |
− | La Libreria può anche essere dichiarata all'interno dell'istruzione di ''Extern'':
| |
− | | |
− | Extern ................. IN "libreria_esterna:num_vers"
| |
− | | |
− | Se il numero della versione della Libreria da dichiarare è complesso, esso andrà scritto così come riportato nel file.
| |
− | Facciamo l'esempio della Libreria ''libsane.so.1.0.23''. Essa sarà scritta così:
| |
− | | |
− | Library "libsane:1.0.23"
| |
− | | |
− | Ugualmente, se la dichiareremo all'interno dell'istruzione di ''Extern'', per chiamare ad esempio la funzione ''sane_init()'':
| |
− | | |
− | Private Extern sane_init() In "libsane:1.0.23"
| |
− | | |
− | Per evitare che la versione della Libreria richiamata non coincida con la versione effettivamente presente in un sistema operativo, si può porre anche solo il primo numero della versione. In tal caso sarà caricata comunque la versione più recente che comincia per il numero indicato.
| |
− | | |
− | Quindi, invece di scrivere per esempio:
| |
− | Library "libsane:1.0.23"
| |
− | si scriverà semplicemente:
| |
− | Library "libsane:1"
| |
− | | |
− | | |
− | ====Ordine delle dichiarazioni nel codice del programma====
| |
− | La funzione vera e propria, da richiamare per il suo utilizzo, sarà posta all'interno di una routine. Dunque, nel caso di dichiarazione separata della Libreria, la scaletta delle dichiarazioni sarà la seguente:
| |
− | <BR>1) dichiarazione della '''Libreria''' contenente la funzione;
| |
− | <BR>2) dichiarazione mediante '''''Extern''''' della funzione esterna che si andrà ad utilizzare (questa dichiarazione avverrà <SPAN style="text-decoration:underline">al di fuori</span> della routine che farà uso di quella funzione);
| |
− | <BR>3) chiamata ed uso della '''funzione''' esterna.
| |
− | | |
− | Esempio astratto:
| |
− | | |
− | <Font Color= #006400>' ''Gambas class file''</font>
| |
− |
| |
− | <Font Color= #006400>' ''dichiariamo la Libreria contenente la funzione esterna che ci interessa:''</font>
| |
− | <Font Color= #FF0000>Library "libreria_esterna:num_vers"</font>
| |
− |
| |
− |
| |
− | <Font Color= #006400>' ''dichiariamo la funzione esterna specifica che ci interessa.
| |
− | ' ''Ipotizziamo che in C sia così scritta: '''int funzione_esterna_da_richiamare(char valoreStringa, int valoreInteger)'''.
| |
− | ' ''Alla funzione esterna vanno passati due valori: uno è una Stringa, l'altro è un Integer. Essa restituirà un valore Integer.
| |
− | ' ''In Gambas la dichiameremo così:''</font>
| |
− | Private <Font Color= #FF0000>EXTERN funzione_esterna_da_richiamare(valoreA As String, ValoreB As Integer) As Integer</font>
| |
− |
| |
− | '''Public''' Sub routine_esempio(primoValore As String, secondoValore As Integer) ''<Font Color= #006400>' poniamo il caso che vengano passati i due valori alla routine necessari per la funzione esterna.''</font>
| |
− |
| |
− | Dim rit_funz As Integer
| |
− |
| |
− | <Font Color= #006400>' ''chiamiamo la funzione esterna che ci interessa,''
| |
− | ' ''e le passiamo i due valori ricevuti dalla routine, perché li elabori:''</font>
| |
− | <Font Color= #FF0000>rit_funz = funzione_esterna_da_richiamare(primoValore, secondoValore)</font>
| |
− |
| |
− | Print rit_funz
| |
− |
| |
− | '''End'''
| |
− | | |
− | ====Uso di due o più funzioni esterne contenute ciascuna in una diversa Libreria====
| |
− | | |
− | Può accadere la necessità di utilizzare funzioni che sono contenute in due o più Librerie. In tal caso bisogna ricordare che la dichiarazione di una Libreria influenzerà ogni dichiarazione con ''Extern'' successiva. Cosicché, in questo caso, bisognerà dichiarare la Libreria corrispondente <SPAN style="text-decoration:underline">prima</span> di ''Extern'' e della routine contenente la funzione da utilizzare:
| |
− | | |
− | <Font Color= #FF0000>Library "1^_libreria_esterna:num_vers"</font>
| |
− |
| |
− | Private <Font Color= #FF0000>EXTERN funzione_esterna(valoreA As ..., ValoreB As ...) As ...</font>
| |
− |
| |
− | '''Public''' Sub prima_routine_esempio(Aval As ..., Bval As ....)
| |
− | ......<Font Color= #006400>' ''qui l'uso della 1^ funzione esterna''</font>
| |
− | '''End'''
| |
− |
| |
− |
| |
− | <Font Color= #FF0000>Library "2^_libreria_esterna:num_vers"</font>
| |
− |
| |
− | Private <Font Color= #FF0000>EXTERN funzione_esterna(valoreC As ..., ValoreD As ...) As ...</font>
| |
− |
| |
− | '''Public''' Sub seconda_routine_esempio(Cval As ..., Dval As ...)
| |
− | ......<Font Color= #006400>' ''qui l'uso della 2^ funzione esterna''</font>
| |
− | '''End'''
| |
− | | |
− | Qualora nell'esempio precedente fosse necessario richiamare, per utilizzare, una funzione esterna presente nella 1^ Libreria, si dovrà dichiarare <SPAN style="text-decoration:underline">nuovamente</span> la 1^ Libreria.
| |
| | | |
| ===Esempi pratici=== | | ===Esempi pratici=== |
Versione delle 04:01, 7 apr 2012
Thess,Sorry about that rotten meal! And the meakrt! That photo is outstandin, though. I love masks, and I find this image very engaging. Your story reminds me of the James Joyce short story "Araby." Thanks for stopping by this a.m.
Esempi pratici
Mostriamo appresso un esempio pratico utilizzando una funzione esterna di ALSA{2}.
1) Il quid:
vogliamo far sì che il nostro applicativo si connetta con ALSA o con un client;
2) per ottenere questo risultato sappiamo che è necessario richiamare una specifica, particolare funzione esterna di ALSA:
int snd_seq_connect_to(snd_seq_t *seq, int my_port, int dest_client, int dest_port)
Questa funzione va così interpretata:
- int : vuol dire che ritorna un valore integer;
- snd_seq_connect_to : è la funzione in sé;
- (snd_seq_t *seq, int my_port, int dest_client, int dest_port) : sono i parametri della funzione. In questo caso: un Pointer (definito dal simbolo *) e tre valori Integer (definiti da ciascun int);
In Gambas sarà così tradotta:
snd_seq_connect_to(primoValore As Pointer, secondoValore As Integer, terzoValore As Integer, quartoValore As Integer) As Integer (quest'ultimo "As Integer" è ovviamente giustificato dal fatto che la funzione, come sappiamo, restituisce un valore integer);
3) il luogo ove questa funzione è contenuta: questa funzione è presente nella Libreria contenente le funzioni di ALSA: Libasound.so.2 .
Il tutto, allora, sarebbe così da impostarsi:
' Dichiarazione della Libreria contenente la funzione esterna che si intende utilizzare:
Library "libasound:2"
....
' Extern dichiara la funzione esterna che si intende richiamare ed utilizzare (lasciamo per comodità qui i nomi: 1°valore, etc, precedentemente usati):
Private Extern snd_seq_connect_to(primoValore As Pointer, secondoValore As Integer, terzoValore As Integer, quartoValore As Integer) As Integer
' Anche in questo caso la routine riceverà i valori da passare alla funzione esterna:
Public Sub chiamtaEsterna(primoVal As Pointer, secondoVal As Integer, terzoVal As Integer, quartoVal As Integer)
Dim err As Integer
' viene praticamente richiamata ed utilizzata la funzione esterna, e le si passano i quattro valori da essa richiesti:
err = snd_seq_connect_to(primoVal, secondoVal, terzoVal, quartoVal)
......
End
Altro esempio pratico:
' Dichiarazione della Libreria contenente le funzioni esterne da utilizzare
(in questo esempio la libreria delle funzioni matematiche):
Library "libm:6"
' Dichiarazione mediante Extern delle funzioni esterne da utilizzare:
Private Extern modf(param As Float, pp As Pointer) As Float
Private Extern fmod(param1 As Float, param2 As Float) As Float
Public Sub Button1_Click()
Dim pp As Pointer = Alloc(SizeOf(gb.Float))
' Uso delle funzioni esterne, e ne vediamo in console il risultato:
Print modf(5.123456, pp)
Print fmod(5.654321, 2)
End
Note
[1] Prendiamo come esempio il rapporto fra Gambas ed il sistema sonoro ALSA. Se non si avesse la possibilità di richiamare, e quindi di utilizzare le funzioni proprie di ALSA, non sarebbe possibile interloquire con questo sistema esterno. Non sarebbe possibile gestirne le capacità, e dunque utilizzare le sue funzioni e potenzialità. L'istruzione Extern ci consente di superare questo muro, questo limite.
[2] Gli applicativi per la gestione del Midi, presenti nella pagina "Progetti degli utenti" del Forum di questo portale Gambas-it.org, abbondano di richiami alle funzioni esterne delle API di ALSA.