Differenze tra le versioni di "Scrivere una libreria esterna contenente una Funzione di Callback che chiama una Funzione Callback in Gambas"

Da Gambas-it.org - Wikipedia.
 
(4 versioni intermedie di uno stesso utente non sono mostrate)
Riga 2: Riga 2:
  
 
[[Extern:_richiamare_funzioni_esterne_a_Gambas#Funzione_esterna_che_fa_riferimento_ad_una_funzione_interna_Callback|Come sappiamo]] è possibile passare l'indirizzo di una ''Funzione CallBack'' di Gambas ad una ''Funzione di Callback'' presente in una libreria esterna. In questa pagina vedremo come scrivere un'apposita libreria esterna contenente una ''Funzione di Callback'', alla quale viene passato l'indirizzo di una ''Funzione Callback'' presente nel codice dell'applicativo Gambas.
 
[[Extern:_richiamare_funzioni_esterne_a_Gambas#Funzione_esterna_che_fa_riferimento_ad_una_funzione_interna_Callback|Come sappiamo]] è possibile passare l'indirizzo di una ''Funzione CallBack'' di Gambas ad una ''Funzione di Callback'' presente in una libreria esterna. In questa pagina vedremo come scrivere un'apposita libreria esterna contenente una ''Funzione di Callback'', alla quale viene passato l'indirizzo di una ''Funzione Callback'' presente nel codice dell'applicativo Gambas.
 
  
 
Facciamo qualche esempio.
 
Facciamo qualche esempio.
 
  
 
===Primo esempio===
 
===Primo esempio===
La libreria esterna, da noi scritta e che chiameremo ''libadhoc.c'', sarà la seguente:
+
In questo esempio, la libreria esterna, da noi scritta in linguaggio C e che chiameremo ''libadhoc.c'' sarà inserita, per maggiore praticità, nel programma principale di Gambas.
#include <unistd.h>
+
  Library "/tmp/libadhoc"
   
 
 
   
 
   
  <FONT Color=blue>int (*po)(int)</font>;  <FONT color=gray>// Dichiarazione del "Puntatore a Funzione"</font>
+
  <FONT Color=gray>' ''void invia(void (*fp))''</font>
+
  Private Extern invia(<FONT Color=#B22222>ricP As Pointer</font>)
 
void invia(<FONT Color=#B22222>void (*fp)</font>) {    <FONT color=gray>// Funzione di Callback</font>
 
 
  int i = 0;
 
 
  <FONT Color=blue>po</font> = <FONT Color=#B22222>fp</font>;  <FONT color=gray>// Inizializzazione del "Puntatore a Funzione"</font>
 
 
 
  while (i < 100) {
 
 
 
<FONT color=gray>/* Invoca la funzione callback di Gambas mediante il "Puntatore a Funzione"
 
    e le passa il valore della variabile intera "i": */</font>
 
    if ((i % 10) == 0)  <FONT Color=blue>(*po)(i)</font>;
 
 
    usleep(50000);
 
   
 
    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 invia(<FONT Color=#B22222>ricP As Pointer</font>) In "/tmp/libadhoc"
 
 
   
 
   
 
   
 
   
 
  '''Public''' Sub Main()
 
  '''Public''' Sub Main()
 
   
 
   
   Shell "gcc -o /tmp/libadhoc.so " & Application.Path &/ "libadhoc.c -shared -fPIC" Wait
+
<FONT Color=gray>' ''Va a creare la nostra libreria condivisa esterna:''</font>
 +
   Creaso()
 
   
 
   
  <FONT Color=gray>' ''Invoca la "Funzione di Callback" della libreria esterna,''
+
  <FONT Color=gray>' ''Invoca la "Funzione di Callback" della libreria esterna, passandole l'indirizzo della "Funzione Callback" di Gambas:''</font>
' ''passandole l'indirizzo della "Funzione Callback" di Gambas:''</font>
 
 
   invia(<FONT Color=#B22222>riceve</font>)
 
   invia(<FONT Color=#B22222>riceve</font>)
 
   
 
   
 
  '''End'''
 
  '''End'''
 +
 
 
   
 
   
 +
'''Private''' Function <FONT Color=#B22222>riceve</font>(i As Integer)  <FONT color=gray>' ''Funzione Callback''</font>
 +
 
 +
  Print "Ricevuto: "; i
 +
 
 +
'''End'''
 
   
 
   
 
   
 
   
  '''Private''' Function <FONT Color=#B22222>riceve</font>(i As Integer)   <FONT color=gray>' ''Funzione Callback''</font>
+
  '''Private''' Procedure Creaso()
 +
 
 +
  File.Save("/tmp/libadhoc.c", "#include <unistd.h>" &
 +
            "\n\n" &
 +
            "<FONT Color=blue>int (*po)(int)</font>;  <FONT color=gray>// Dichiarazione del 'Puntatore a Funzione'</font>" &
 +
            "\n\n" &
 +
            "void invia(<FONT Color=#B22222>void (*fp)</font>) {    <FONT color=gray>// Funzione di Callback</font>" &
 +
            "\n\n" &
 +
            "  int i = 0;" &
 +
            "\n\n" &
 +
            "  <FONT Color=blue>po</font> = <FONT Color=#B22222>fp</font>;  <FONT color=gray>// Inizializzazione del 'Puntatore a Funzione'</font>" &
 +
            "\n\n" &
 +
            "  while (i < 100) {\n" &
 +
            "<FONT color=gray>/* Invoca la 'funzione callback' di Gambas mediante il 'Puntatore a Funzione' e le passa il valore della variabile intera 'i': */</font>\n" &
 +
            "    if ((i % 10) == 0)  <FONT Color=blue>(*po)(i)</font>;\n" &
 +
            "      usleep(50000);\n" &
 +
            "    i++;\n}\n\n}")
 
    
 
    
  Print "Ricevuto: "; i
+
  Shell "gcc -o /tmp/libadhoc.so /tmp/libadhoc.c -shared -fPIC" Wait
 
    
 
    
 
  '''End'''
 
  '''End'''
Riga 62: Riga 56:
  
 
===Secondo esempio===
 
===Secondo esempio===
La libreria esterna, da noi scritta e che chiameremo ''libadhoc.c'', sarà la seguente:
+
Quest'altro esempio è molto simile al precedente, ma attribuiamo l'indirizzo di memoria della funzione di Callback di Gambas ad una variabile di tipo Puntatore.
  void Funzione_C(int i, void (*Funzione_Gambas)(int)) {
+
  Library "/tmp/libadhoc"
 
   
 
   
  int n = 100;
+
<FONT Color=gray>' ''void Funzione_di_Callback(int i, void (*Funzione_Callback)(int))''
  int a;
+
' ''Funzione di callback.</font>
 +
Private Extern <FONT Color=blue>Funzione_di_Callback</font>(i As Integer, <FONT Color=#B22222>Funzione_Callback</font> As Pointer) In "/tmp/libadhoc"
 +
 +
 +
'''Public''' Sub Main()
 
    
 
    
  for (i = 0; i < n ; i++) {
+
  Dim p As Pointer
      a = i * n;
 
      Funzione_Gambas(a);
 
  }
 
 
    
 
    
}
+
  CreaSo()
 
+
 
 
+
  <FONT Color=green><B>p</b></font> = <FONT Color=#B22222>riceve</font>
L'applicativo Gambas sarà invece il seguente:
+
 
Public Extern Funzione_C(i As Integer, FunzioneCallback As Pointer) In "/tmp/libadhoc"
+
  <FONT Color=blue>Funzione_di_Callback</font>(10, <FONT Color=green><B>p</b></font>)
 +
 
 +
'''End'''
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  '''Private''' Procedure CreaSo()
+
 
   Shell "gcc -o /tmp/libadhoc.so " & Application.Path &/ "libadhoc.c -shared -fPIC" Wait
+
  File.Save("/tmp/libadhoc.c", "void <FONT Color=blue>Funzione_di_Callback</font>(int i, <FONT Color=#B22222>void (*Funzione_Callback)(int)</font>) {" &
 +
            "\n\n" &
 +
            "  int n = 100;\n" &
 +
            "  int a;\n" &
 +
            "\n\n" &
 +
            "  for (i = 0; i < n ; i++) {\n" &
 +
            "    a = i * n;\n" &
 +
            "    <FONT Color=#B22222>Funzione_Callback(a)</font>;\n" &
 +
            "  }\n\n}")
 +
           
 +
   Shell "gcc -o /tmp/libadhoc.so /tmp/libadhoc.c -shared -fPIC" Wait
 
    
 
    
  Funzione_C(10, Funzione_Callback)
 
 
 
  '''End'''
 
  '''End'''
 
   
 
   
 
   
 
   
  '''Private''' Sub Funzione_Callback(ris As Integer)
+
  '''Private''' Function <FONT Color=#B22222>riceve(rit As Integer)</font>  <FONT Color=gray>' ''Funzione Callback''</font>
   
+
 
   Print ris
+
   Print "Ricevuto: "; rit
 
   
 
   
 
  '''End'''
 
  '''End'''
Riga 99: Riga 104:
 
===Terzo esempio===
 
===Terzo esempio===
 
In quest'altro esempio la ''Funzione di Callback'', presente nella libreria esterna ''ad hoc'', non ritornerà alcun dato alla ''funzione callback'' presente in Gambas.
 
In quest'altro esempio la ''Funzione di Callback'', presente nella libreria esterna ''ad hoc'', non ritornerà alcun dato alla ''funzione callback'' presente in Gambas.
<BR>Il codice in linguaggio C della ''funzione di callback'' sarà inserito, per maggiore praticità, nel programma principale di Gambas.
 
 
  Library "/tmp/libadhoc"
 
  Library "/tmp/libadhoc"
 
   
 
   
  <FONT Color=gray>' ''void Funzione_di_Callback(<FONT Color=#B22222>void *fp(void)</font>)''
+
  <FONT Color=gray>' ''void <FONT Color=blue>Funzione_di_Callback</font>(<FONT Color=#B22222>void *Funzione_Callback(void)</font>)''
 
  ' ''Funzione di callback.''</font>
 
  ' ''Funzione di callback.''</font>
  Private Extern Funzione_di_Callback(fp As Pointer)
+
  Private Extern <FONT Color=blue>Funzione_di_Callback</font>(<FONT Color=#B22222>Funzione_Callback</font> As Pointer)
 
   
 
   
 
   
 
   
Riga 114: Riga 118:
 
  <FONT Color=gray>' ''Invoca la "funzione di callback", contenuta nella libreria esterna da noi generata,''
 
  <FONT Color=gray>' ''Invoca la "funzione di callback", contenuta nella libreria esterna da noi generata,''
 
  ' ''e le passa la "funzione callback" presente di seguito in questo progetto Gambas:''</font>
 
  ' ''e le passa la "funzione callback" presente di seguito in questo progetto Gambas:''</font>
   Funzione_di_Callback(<FONT Color=#B22222>riceve</font>)
+
   <FONT Color=blue>Funzione_di_Callback</font>(<FONT Color=#B22222>riceve</font>)
 
    
 
    
 
  '''End'''
 
  '''End'''
Riga 121: Riga 125:
 
  '''Private''' Procedure CreaSo()
 
  '''Private''' Procedure CreaSo()
 
    
 
    
   File.Save("/tmp/libadhoc.c", "void Funzione_di_Callback(<FONT Color=#B22222>void *fp(void)</font>) {\n" &
+
   File.Save("/tmp/libadhoc.c", "void <FONT Color=blue>Funzione_di_Callback</font>(<FONT Color=#B22222>void *Funzione_Callback(void)</font>) {" &
             "  <FONT Color=#B22222>fp()</font>;\n}")
+
            "\n\n" &
 +
             "  <FONT Color=#B22222>Funzione_Callback()</font>;\n\n}")
 
              
 
              
 
   Shell "gcc -o /tmp/libadhoc.so /tmp/libadhoc.c -shared" Wait
 
   Shell "gcc -o /tmp/libadhoc.so /tmp/libadhoc.c -shared" Wait
Riga 129: Riga 134:
 
   
 
   
 
   
 
   
  '''Private''' Function riceve()  <FONT Color=gray>' ''Funzione Callback''</font>
+
  '''Private''' Function <FONT Color=#B22222>riceve()</font>   <FONT Color=gray>' ''Funzione Callback''</font>
 
   
 
   
 
   Print "Ricevuto !"
 
   Print "Ricevuto !"
 
    
 
    
 
  '''End'''
 
  '''End'''

Versione attuale delle 13:11, 20 feb 2021

La "Funzione Callback" è una funzione, della quale viene passato mediante una variabile di tipo Puntatore l'indirizzo ad una funzione di libreria (Funzione di Callback) in modo tale che al momento previsto questa Funzione di Callback della libreria possa chiamare la Funzione Callback, eventualmente anche passandole dei parametri.

Come sappiamo è possibile passare l'indirizzo di una Funzione CallBack di Gambas ad una Funzione di Callback presente in una libreria esterna. In questa pagina vedremo come scrivere un'apposita libreria esterna contenente una Funzione di Callback, alla quale viene passato l'indirizzo di una Funzione Callback presente nel codice dell'applicativo Gambas.

Facciamo qualche esempio.

Primo esempio

In questo esempio, la libreria esterna, da noi scritta in linguaggio C e che chiameremo libadhoc.c sarà inserita, per maggiore praticità, nel programma principale di Gambas.

Library "/tmp/libadhoc"

' void invia(void (*fp))
Private Extern invia(ricP As Pointer)


Public Sub Main()

' Va a creare la nostra libreria condivisa esterna:
  Creaso()

' Invoca la "Funzione di Callback" della libreria esterna, passandole l'indirizzo della "Funzione Callback" di Gambas:
  invia(riceve)

End
 

Private Function riceve(i As Integer)   ' Funzione Callback
 
  Print "Ricevuto: "; i
 
End


Private Procedure Creaso()
 
 File.Save("/tmp/libadhoc.c", "#include <unistd.h>" &
           "\n\n" &
           "int (*po)(int);   // Dichiarazione del 'Puntatore a Funzione'" &
           "\n\n" &
           "void invia(void (*fp)) {    // Funzione di Callback" &
           "\n\n" &
           "   int i = 0;" &
           "\n\n" &
           "   po = fp;   // Inizializzazione del 'Puntatore a Funzione'" &
           "\n\n" &
           "   while (i < 100) {\n" &
           "/* Invoca la 'funzione callback' di Gambas mediante il 'Puntatore a Funzione' e le passa il valore della variabile intera 'i': */\n" &
           "     if ((i % 10) == 0)  (*po)(i);\n" &
           "       usleep(50000);\n" &
           "     i++;\n}\n\n}")
 
 Shell "gcc -o /tmp/libadhoc.so /tmp/libadhoc.c -shared -fPIC" Wait
 
End


Secondo esempio

Quest'altro esempio è molto simile al precedente, ma attribuiamo l'indirizzo di memoria della funzione di Callback di Gambas ad una variabile di tipo Puntatore.

Library "/tmp/libadhoc"

' void Funzione_di_Callback(int i, void (*Funzione_Callback)(int))
' Funzione di callback.
Private Extern Funzione_di_Callback(i As Integer, Funzione_Callback As Pointer) In "/tmp/libadhoc"


Public Sub Main()
 
 Dim p As Pointer
 
 CreaSo()
 
 p = riceve
 
 Funzione_di_Callback(10, p)
 
End


Private Procedure CreaSo()
 
 File.Save("/tmp/libadhoc.c", "void Funzione_di_Callback(int i, void (*Funzione_Callback)(int)) {" &
           "\n\n" &
           "   int n = 100;\n" &
           "   int a;\n" &
           "\n\n" &
           "   for (i = 0; i < n ; i++) {\n" &
           "     a = i * n;\n" &
           "     Funzione_Callback(a);\n" &
           "   }\n\n}")
           
 Shell "gcc -o /tmp/libadhoc.so /tmp/libadhoc.c -shared -fPIC" Wait
 
End


Private Function riceve(rit As Integer)   ' Funzione Callback
 
 Print "Ricevuto: "; rit

End


Terzo esempio

In quest'altro esempio la Funzione di Callback, presente nella libreria esterna ad hoc, non ritornerà alcun dato alla funzione callback presente in Gambas.

Library "/tmp/libadhoc"

' void Funzione_di_Callback(void *Funzione_Callback(void))
' Funzione di callback.
Private Extern Funzione_di_Callback(Funzione_Callback As Pointer)


Public Sub Main()
 
' Crea la libreria esterna contenente la "funzione di callback":
 CreaSo()
 
' Invoca la "funzione di callback", contenuta nella libreria esterna da noi generata,
' e le passa la "funzione callback" presente di seguito in questo progetto Gambas:
 Funzione_di_Callback(riceve)
  
End


Private Procedure CreaSo()
 
 File.Save("/tmp/libadhoc.c", "void Funzione_di_Callback(void *Funzione_Callback(void)) {" &
           "\n\n" &
           "  Funzione_Callback();\n\n}")
           
 Shell "gcc -o /tmp/libadhoc.so /tmp/libadhoc.c -shared" Wait
 
End


Private Function riceve()   ' Funzione Callback

 Print "Ricevuto !"
  
End