« De profundis clamavi te, functio externa ! »
Preambulo
Para utilizar las funciones externas en gambas, es oportuno:
1) tener un conocimiento por lo menos elemental del lenguaje C;
2) conocer el funcionamento de las funciones en Gambas.
Introducción
gambas permite utilizar potencialidad y capacidad de sistemas a través de la llamada de funciones externas. A veces en efecto puede ocurrir en la programación la necesidad de utilizar potencialidad que gambas no puede ofrecer. La instrucción que gambas pone a disposición del programador para llamar tales funciones externas es: Extern.
Por la llamada de funciones externas es necesario conocer en particular tres elementos:
1) el quid o sea lo que hacer, lo que conseguir;
2) la función externa que nos permite realizar aquel quid;
3) la librería en la que es contenida la función por volver a llamarla.
Si lo que se quiere conseguir sólo es posible por el empleo de una función externa a gambas, hará falta localizar la específica función que permite realizar nuestro objetivo. La función externa, útil al objetivo del programa, tendrá que ser llamada por nuestro programa gambas. Ya que tal función externa es escrita en C, hará falta interpretar el significado y traducirla en forma comprensible para gambas. Además, ya que ella es exterior a gambas, hará falta conocer el lugar donde ella se encuentra. El lugar que contiene la función externa es la "Librería"; y más bien una específica librería, ella que, por tanto, deberá ser declarada en antelación con respecto de la función.
Las librerías, que contienen funciones externas a gambas, utilizables por gambas, son aquellas con extensión .so, o sea las "Librerías dinámicas" (shared library).
Es oportuno, cuando posible, también indicar el número de la versión de la Librería. Además, si la librería se encuentra en una carpeta diferente de aquél dedicado a las librerías (/usr/lib/), será necesario también precisar la su ruta.
Identificación y declaración de la Librería que contiene la Función externa
La Librería, que contiene la función externa que tenemos que llamar, puede ser declarada separadamente, y antes de la declaración Extern, a través de la palabra Library:
La Librería, pero, puede ser también declarada dentro de la instrucción de Extern a través de la palabra In:
Si el número de la versión de la Librería es complejo, deberá ser escrito tal como indicado en el fichero de la Librería. La parte .so. debe ser reemplazada con el carácter de los dos puntos ( : ).
Hacemos el ejemplo de la Librería libsane.so.1.0.23
Ella será escrita así:
Library "libsane:1.0.23"
Declaración de la Función externa mediante Extern
La Función externa, que tenemos que utilizar, debe ser declarada mediante la instrucción Extern. Esta declaración tiene que ser efectuada externamente a las rutinas.
La declaración tiene que contener:
1) el nombre de la función externa que utilizaremos;
2) la especificación de los eventuales argumentos de la función externa (tal como por las funciones de gambas);
3) el eventual valor de regreso.
La declaración puede ser "Public" o "Private".
Un ejemplo abstracto de declaración de una función externa declarada en C en esta manera:
int nombre_función(int valor1, char valor2)
en gambas serà declarada:
Orden de las declaraciones en el código del programa
La función real, que tenemos que llamar por su empleo, será puesta dentro de una rutina. Pues, en el caso de declaración separada de la Librería, el guión de las declaraciones será:
1) declaración de la Librería que contiene la función;
2) declaración a través de Extern de la función externa que se utilizará (esta declaración ocurrirá fuera de la rutina que utilizará aquella función);
3) llamada y empleo de la función externa.
En este ejemplo abstracto la función externa que tenemos que utilizar es declarada en C:
Pues los dos argumentos de la función son: una cadena y un Integer. Ella regresa un valor Integer.
Bueno, el codigo de ejemplo en Gambas:
Library "libreria_externa:num_version"
' En gambas la declararemos asì:
Private Extern functio_externa($val As String, Ival As Integer) As Integer
' La función serà utilizada en las rutinas por ejemplo asì:
Public Sub Button1_Click()
Dim primeroValor As String
Dim segundoValor As Integer
Dim rit_funz As Integer
primeroValor = "una cadena"
segundoValor = 1000
rit_funz = functio_externa(primeroValor, segundoValor)
' Vamos a ver en console el valor regresado por la función externa:
Print rit_funz
End
' En gambas la declararemos asì:
Private Extern functio_externa($val As String, Ival As Integer) As Integer
' La función serà utilizada en las rutinas por ejemplo asì:
Public Sub Button1_Click()
Dim primeroValor As String
Dim segundoValor As Integer
Dim rit_funz As Integer
primeroValor = "una cadena"
segundoValor = 1000
rit_funz = functio_externa(primeroValor, segundoValor)
' Vamos a ver en console el valor regresado por la función externa:
Print rit_funz
End
Ejemplo practico
Ahora vamos a ver un ejemplo practico, donde tenemos dos funciones externas matematicas de la libreria libm .
Library "libm:6"
' double modf(double x, double *integer)
' Returns the fraction component (part after the decimal), and sets integer to the integer component.
Private Extern modf(xF As Float, pp As Pointer) As Float
' double fmod(double x, double y)
' Returns the remainder of x divided by y.
Private Extern fmod(xF As Float, yF As Float) As Float
Public Sub Main()
Dim p As Pointer = Alloc(SizeOf(gb.Float))
Print modf(5.123456, p)
Print fmod(5.654321, 2)
Free(p)
End
' double modf(double x, double *integer)
' Returns the fraction component (part after the decimal), and sets integer to the integer component.
Private Extern modf(xF As Float, pp As Pointer) As Float
' double fmod(double x, double y)
' Returns the remainder of x divided by y.
Private Extern fmod(xF As Float, yF As Float) As Float
Public Sub Main()
Dim p As Pointer = Alloc(SizeOf(gb.Float))
Print modf(5.123456, p)
Print fmod(5.654321, 2)
Free(p)
End