Dichiarazioni di funzioni esterne
{ PUBLIC | PRIVATE } EXTERN
Identificatore
(
[ Parametro AS TipoDato [ , ... ] ]
)
[ AS TipoDato ]
[ IN Libreria ] [ EXEC Alias ]
Questo è il modo per far conoscere a Gambas che intendiamo accedere ad una funzione non interna a Gambas, ma bensì posizionata in una libreria cnodivisa.
Argomenti
I parametri di una funzione esterna, possono essere uno qualsiasi dei tipi di dato gestiti da
Gambas ad esclusione del tipo
Variant.
Gambas automaticamente, presenterà questi tipi di dato che saranno compatibili con quelli che la macchina si aspetta.
Quando si passa un oggetto, la funzione riceve un puntatore a questi dati e se l'oggetto è una classe, allora la funzione, riceverà un puntatore ai dati statici della classe in questione.
Ovviamente per un argomento pointer usate il tipo di dati
Pointer.
È possibile utilizzare gli argomenti
String, a meno che la funzione non li modifichi, poiché in Gambas i valori
String sono costanti condivise.
Argomenti del puntatore
Se è necessario inviare un puntatore a una variabile, è possibile utilizzare la funzione
VarPtr, ma solo per argomenti non stringa.
Esempi
EXTERN GetAFloat(Result AS Pointer, A AS Float, B AS Float)
DIM fResult AS Float
GetAFloat(VarPtr(fResult), Pi, Pi(2))
Utilizza il puntatore anche quando l'argomento della funzione extern è un tipo di dimensione di memoria (ad esempio size_t), poiché questi tipi hanno la stessa dimensione intera di un void *
.
Callbacks di funzioni
Alcune funzioni esterne possono utilizzare un puntatore a funzione come argomento, questo puntatore a funzione viene utilizzato come callback.
Per usare una funzione Gambas come una callback:
-
Basta dichiarare l'argomento puntatore alla funzione come
Pointer
nella dichiarazione di funzione extern.
-
Utilizzare il nome della funzione Gambas come argomento della funzione extern.
Esempio
Private Extern qsort(base As Pointer, nmemb As Pointer, size As Pointer, compar As Pointer) In "libc:6"
Private Sub Compare(pA As Pointer, pB As Pointer) As Integer
...
End
Public Sub Main()
Dim aVal As Integer[]
...
qsort(aVal.Data, aVal.Count, 4, Compare)
...
End
Notate che potete usare una funzione Gambas sia pubblica che privata. Potete sempre usare un metodo non statico, ma state attenti che il metodo (metodo) dell'oggetto (object) passato non sia catturato dalla callback e rilasciato quindi solo al termine del programma!
Valore di ritorno
Il valore di ritorno di una funzione chiamata da extern, può essere di un qualsiasi tipo di dati di Gambas ad esclusione del tipo
Object e
Variant. Questo per ovvi motivi in quanto non esistendo il tipo variant in C/C++ ed essendo il modello dell'oggetto diverso in Gambas dal C/C++, la loro assegnazione sarebbe impossibile.
Attenzione! Se una funzione extern restituisce una stringa, allora Gambas restituirà una copia di essa.
Se viceversa avete la necessità di avere come valore restituito il reale contenuto della stringa, allora basta usare il tipo di dati puntatore (
Pointer) con la funzione di conversione
StrPtr.
Nome della libreria
Il nome della libreria viene specificato con l'argomento
Library. Se questo non viene specificato, allora viene utilizzato come nome l'ultimo da voi usato.
Il nome della libreria deve essere il nome del file senza l'esensione e il numero di versione.
Se volete utilizzare la libreria grafica OpenGL, per esempio il cui vero nome è
libGL.so.1
, il nome che dovrete usare con Gambas è
libGL
. Se viceversa volete utilizzare una versione specifica, allora alla fine del nome della libreria, dovete aggiungere i due punti (:) e il numero della versione desiderata.
Per esempio per usare specificatamente la libreria OpenGL versione 1.0.7667, dovrete digitare libGL:1.0.7667.
Esempi
' La necessità di usare la funzione ioctl della libreria libc.
EXTERN ioctl(fd AS Integer, op AS Integer, arg AS Pointer) AS Integer IN "libc:6"
...
Err = ioctl(MyStream.Handle, ... )
Nome funzione
Il nome di una funzione nella libreria esterna ha come nome predefinito il nome della funzione in Gambas (esempio
/wiki/..def/identifier. Se per motivi vostri volete utilizzare nomi che entrerebbero in conflitto con le parole chiave usate in Gambas, potete utilizzare la parola chiave
EXEC
.
Esempi
' Il nome di questa funzione , è una parola riservata (Open) in Gambas!
EXTERN SysOpen(Name AS String, Flags AS Integer, Mode AS Integer) AS Integer IN "libc:6" EXEC "Open"
Vedi anche