Scrivere una libreria esterna che chiama una funzione esterna puntata

Da Gambas-it.org - Wikipedia.

Una libreria esterna appositamente può essere scritta per utilizzare una funzione esterna puntata da un Puntatore.


Nel seguente esempio abbiamo un codice sorgente in linguaggio C, che chiameremo "sorgente_C.c", nel quale è presente la funzione che vogliamo utilizzare e che è puntata da un Puntatore a Funzione:

int Funzione_Puntata(int valore) {

  return valore + 1;

}


La libreria esterna, da noi scritta e che chiameremo libadhoc.c, sarà la seguente:

#include <stdio.h>
#include "/percorso/del/file/sorgente_C.c"


int (*po)(int);


int Chiamata_Funzione(int i) {
 
  po = Funzione_Puntata;   //inizializzazione del Puntatore a funzione

  return (*po)(i);

}

Il codice sorgente della libreria esterna, da noi scritta, verrà posto nella cartella Dati del progetto Gambas.


L'applicativo Gambas sarà invece il seguente:

Private i As Integer


Private Extern Chiamata_Funzione(vI As Integer) As Integer In "/tmp/libadhoc"


Public Sub Form_Open()

' Genera la libreria esterna condivisa da noi scritta:
  Shell "gcc -o /tmp/libadhoc.so " & Application.Path &/ "libadhoc.c -shared  -fPIC" Wait

End


Public Sub Button1_Click()

  i = Chiamata_Funzione(i)

  Print "Valore ritornato dalla funzione-puntatore: "; i

End


Uso della sola libreria esterna condivisa .so

Il codice presente nel file sorgente_C.c dell'esempio precedente può anche essere più semplicemente contenuto nella sola libreria esterna condivisa .so, come segue:

#include <stdio.h>


int (*po)(int));


int Funzione_Puntata(int valore) {

 return valore + 1;

}


int Chiamata_Funzione(int i) {
 
  po = Funzione_Puntata;   //inizializzazione del Puntatore a funzione
 
  return (*po)(i);

}



Uso del metodo System.GetExternSymbol()

E' possibile utilizzare anche il metodo .GetExternSymbol() della Classe System, come segue (poniamo tutto il codice C nella sola libreria esterna condivisa, che chiameremo libadhoc.so):

#include <stdio.h>


int Funzione_Puntata(int valore) {

  return valore + 1;

}


int Chiamata_Funzione(int (*p)(int), int i) {

   return (*p)(i));

}

Il codice sorgente della libreria esterna, da noi scritta, verrà posto nella cartella Dati del progetto Gambas.


L'applicativo Gambas sarà invece il seguente:

Private Extern Chiamata_Funzione(po As Pointer, i As Integer) As Integer In "/tmp/libadhoc"


Public Sub Main()

 Dim p As Pointer
 Dim i As Integer
 
' Genera la libreria esterna condivisa da noi scritta:
  Shell "gcc -o /tmp/libadhoc.so " & Application.Path &/ "libadhoc.c -shared  -fPIC" Wait

  p = System.GetExternSymbol("/tmp/libadhoc", "Funzione_Puntata")

  i = Chiamata_Funzione(p, 99)
 
  Print i

End


Uso di una semplice variabile di tipo Puntatore

E' possibile utilizzare una semplice variabile di tipo Puntatore al posto del metodo .GetExternSymbol() appena sopra prima visto. A detta variabile di tipo Puntatore sarà assegnata la funzione, presente nella libreria esterna condivisa, da puntare.

Anche questa volta dobbiamo porre tutto il codice C nella sola libreria esterna condivisa, che chiameremo libadhoc.so:

#include <stdio.h>


int Funzione_Puntata(int valore) {

  return valore + 1;

}


int Chiamata_Funzione(int (*p)(int), int i) {

   return (*p)(i));

}

Il codice sorgente della libreria esterna, da noi scritta, verrà posto nella cartella Dati del progetto Gambas.


L'applicativo Gambas sarà invece il seguente:

Library "/tmp/libadhoc" 

Private Extern Chiamata_Funzione(po As Pointer, i As Integer) As Integer
Private Extern Funzione_Puntata()


Public Sub Main()

 Dim p As Pointer
 Dim i As Integer
 
' Genera la libreria esterna condivisa da noi scritta:
  Shell "gcc -o /tmp/libadhoc.so " & Application.Path &/ "libadhoc.c -shared  -fPIC" Wait

  p = Funzione_Puntata

  i = Chiamata_Funzione(p, 99)
 
  Print i

End