Differenze tra le versioni di "Scrivere una libreria esterna alla quale viene passata una struttura"

Da Gambas-it.org - Wikipedia.
 
(7 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
Qualora si debba scrivere una propria libreria dinamica condivisa (.so) esterna, bisognerà tenere conto nel codice sorgente, scritto in C, della libreria esterna di quanto segue:
+
Qualora si debba scrivere una propria libreria condivisa (.so) esterna, alla quale passare da Gambas una ''Struttura'', perché venga gestita e valorizzata, nel codice sorgente della libreria esterna si dovrà tenere conto di quanto segue:
<BR>- si dovrà riprodurre una ''Struttura'' omogenea - in ordine alla tipologia dei suoi membri - alla ''Struttura'' di Gambas passata;
+
<BR>- si riprodurrà una ''Struttura'' omogenea a quella che la funzione esterna riceverà dal codice Gambas;
<BR>- il parametro della funzione della libreria esterna, che riceve la ''Struttura'' di Gambas passata, deve essere dichiarato come ''Puntatore'' alla ''Struttura'' definita nel codice sorgente C della libreria medesima.
+
<BR>- il parametro della funzione della libreria esterna, che riceve la ''Struttura'' passata da Gambas, deve essere dichiarato come ''Puntatore'' al tipo della ''Struttura'' definita nel codice della libreria medesima.
 
 
 
 
Mostriamo un semplice esempio, nel quale verrà creato in linguaggio C il codice sorgente della nostra libreria dinamica condivisa esterna come di seguito:
 
struct STRUTTURA_C {
 
  double x;
 
  double y;
 
  double z;
 
};
 
 
 
double FunzioneEsterna(struct STRUTTURA_C <FONT Color=#B22222><B>*</b></font> sC) {
 
 
  double d;
 
 
 
  d = sC->x + sC->y + sC->z;
 
 
  return d;
 
}
 
 
 
  
 
L'intero codice Gambas, nel quale provvederemo anche a scrivere e creare sia il codice sorgente in C della libreria esterna, sia il file .so della libreria medesima, sarà il seguente:
 
L'intero codice Gambas, nel quale provvederemo anche a scrivere e creare sia il codice sorgente in C della libreria esterna, sia il file .so della libreria medesima, sarà il seguente:
Riga 33: Riga 14:
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
   
 
   
 
   Dim sG As New STRUTTURA_Gambas
 
   Dim sG As New STRUTTURA_Gambas
 
   Dim ris As Float
 
   Dim ris As Float
 
    
 
    
  creaso()
+
  Creaso()
 
    
 
    
  With sG
+
  With sG
    .x = 1.111
+
    .x = 1.111
    .Y = 2.222
+
    .Y = 2.222
    .z = 3.333
+
    .z = 3.333
  End With
+
  End With
 
    
 
    
  ris = FunzioneEsterna(sG)
+
  ris = FunzioneEsterna(sG)
 
    
 
    
  Print ris
+
  Print ris
 
+
 
  '''End'''
+
  End
 +
 
   
 
   
 +
Private Procedure Creaso()
 
   
 
   
'''Private''' Procedure creaso()
+
  File.Save("/tmp/lib_esterna.c", "struct STRUTTURA_C {\n" &
 +
                                  "  double x;\n" &
 +
                                  "  double y;\n" &
 +
                                  "  double z;\n};\n\n" &
 +
                                  "double FunzioneEsterna(struct STRUTTURA_C *sC) {\n" &
 +
                                  "  double d;\n\n" &
 +
                                  "  d = sC->x + sC->y + sC->z;\n\n" &
 +
                                  "  return d;\n}")
 
    
 
    
   Dim s As String
+
  Shell "gcc -o /tmp/lib_esterna.so /tmp/lib_esterna.c -shared" Wait
 +
 +
End
 +
 
 +
 
 +
=Scrivere una libreria esterna alla quale viene passata una struttura e che ritorna una Struttura=
 +
Nel caso in cui la libreria esterna, da noi scritta in C, prevede il passaggio di una ''Struttura'' dal Programma principale Gambas ad una funzione della libreria esterna, con ritorno della medesima ''Struttura'', detto ritorno potrà essere di due tipi:
 +
* ritorno per "Valore" mediante ''return'';
 +
* ritorno per "Indirizzo".
 +
 
 +
In particolare nel ritorno della ''Struttura'' mediante ''return'' la ''Struttura'', passata dal programma Gambas, sarà esplicito oggetto del ritorno mediante ''return'' alla fine della funzione esterna chiamata.
 +
 
 +
Mostriamo un esempio pratico, nel quale verranno mostrati entrambi i casi sopra esposti:
 +
Public Struct STRUTTURA_Gambas
 +
  x As Float
 +
  Y As Float
 +
  z As Float
 +
End Struct
 +
 +
Library "/tmp/libesterna"
 +
 +
<FONT Color=gray>' ''struct STRUTTURA_C * FunzioneEsterna(STRUTTURA_C *p)''</font>
 +
Public Extern FunzioneEsterna(struG As STRUTTURA_Gambas) As STRUTTURA_Gambas
 +
 +
 +
Public Sub Main()
 +
 +
   Dim stG, rit As STRUTTURA_Gambas
 
    
 
    
  s = "struct STRUTTURA_C {" &
+
  creaso()
     "\n  double x;" &
+
   
     "\n  double y;" &
+
  With stG = New STRUTTURA_Gambas
     "\n  double z;\n};" &
+
     .x = 1.111
    "\n\n" &
+
     .Y = 2.222
    "\ndouble FunzioneEsterna(struct STRUTTURA_C *sC) {" &
+
     .z = 3.333
    "\n\n  double d;" &
+
  End With
     "\n\n  d = sC->x + sC->y + sC->z;" &
+
 
    "\n\n  return d;\n}"
+
  rit = FunzioneEsterna(stG)
 +
 
 +
  With rit  <FONT Color=gray>' ''Variabile del tipo "Struttura" ritornata per "Valore"''</font>
 +
     Print .x
 +
    Print .Y
 +
    Print .z
 +
  End With
 
      
 
      
     File.Save("/tmp/lib_esterna.c", s)
+
  With stG  <FONT Color=gray>' ''Variabile del tipo "Struttura" ritornata per "Indirizzo"''</font>
 +
    Print .x
 +
    Print .Y
 +
     Print .z
 +
  End With
 +
 
 +
End
 +
 
 +
 +
Private Procedure creaso()
 
    
 
    
    Shell "gcc -o /tmp/lib_esterna.so /tmp/lib_esterna.c -shared" Wait
+
  File.Save("/tmp/libesterna.c", "struct STRUTTURA_C {" &
 +
            "double x\n;" &
 +
            "double y\n;" &
 +
            "double z;};" &
 +
            "\n\n" &
 +
            "\nstruct STRUTTURA_C * FunzioneEsterna(struct STRUTTURA_C *p) {" &
 +
            "\n\n"
 +
            "  p->x *= 11.11;\n" &
 +
            "  p->y *= 22.22;\n" &
 +
            "  p->z *= 33.33;\n" &
 +
            "  return p;\n}")
 +
 
 +
  Shell "gcc -o /tmp/libesterna.so /tmp/libesterna.c -shared" Wait
 
    
 
    
  '''End'''
+
  End

Versione attuale delle 19:34, 12 giu 2024

Qualora si debba scrivere una propria libreria condivisa (.so) esterna, alla quale passare da Gambas una Struttura, perché venga gestita e valorizzata, nel codice sorgente della libreria esterna si dovrà tenere conto di quanto segue:
- si riprodurrà una Struttura omogenea a quella che la funzione esterna riceverà dal codice Gambas;
- il parametro della funzione della libreria esterna, che riceve la Struttura passata da Gambas, deve essere dichiarato come Puntatore al tipo della Struttura definita nel codice della libreria medesima.

L'intero codice Gambas, nel quale provvederemo anche a scrivere e creare sia il codice sorgente in C della libreria esterna, sia il file .so della libreria medesima, sarà il seguente:

Public Struct STRUTTURA_Gambas
  x As Float
  Y As Float
  z As Float
End Struct

' double FunzioneEsterna(STRUTTURA_C * sC)
Public Extern FunzioneEsterna(struG As STRUTTURA_Gambas) As Float In "/tmp/lib_esterna"


Public Sub Main()

 Dim sG As New STRUTTURA_Gambas
 Dim ris As Float
 
 Creaso()
  
 With sG
   .x = 1.111
   .Y = 2.222
   .z = 3.333
 End With
  
 ris = FunzioneEsterna(sG)
  
 Print ris
 
End


Private Procedure Creaso()

 File.Save("/tmp/lib_esterna.c", "struct STRUTTURA_C {\n" &
                                 "   double x;\n" &
                                 "   double y;\n" &
                                 "   double z;\n};\n\n" &
                                 "double FunzioneEsterna(struct STRUTTURA_C *sC) {\n" &
                                 "   double d;\n\n" &
                                 "   d = sC->x + sC->y + sC->z;\n\n" &
                                 "   return d;\n}")
 
 Shell "gcc -o /tmp/lib_esterna.so /tmp/lib_esterna.c -shared" Wait

End


Scrivere una libreria esterna alla quale viene passata una struttura e che ritorna una Struttura

Nel caso in cui la libreria esterna, da noi scritta in C, prevede il passaggio di una Struttura dal Programma principale Gambas ad una funzione della libreria esterna, con ritorno della medesima Struttura, detto ritorno potrà essere di due tipi:

  • ritorno per "Valore" mediante return;
  • ritorno per "Indirizzo".

In particolare nel ritorno della Struttura mediante return la Struttura, passata dal programma Gambas, sarà esplicito oggetto del ritorno mediante return alla fine della funzione esterna chiamata.

Mostriamo un esempio pratico, nel quale verranno mostrati entrambi i casi sopra esposti:

Public Struct STRUTTURA_Gambas
  x As Float
  Y As Float
  z As Float
End Struct

Library "/tmp/libesterna"

' struct STRUTTURA_C * FunzioneEsterna(STRUTTURA_C *p)
Public Extern FunzioneEsterna(struG As STRUTTURA_Gambas) As STRUTTURA_Gambas


Public Sub Main()

 Dim stG, rit As STRUTTURA_Gambas
 
 creaso()
    
 With stG = New STRUTTURA_Gambas
   .x = 1.111
   .Y = 2.222
   .z = 3.333
 End With
  
 rit = FunzioneEsterna(stG)
  
 With rit   ' Variabile del tipo "Struttura" ritornata per "Valore"
   Print .x
   Print .Y
   Print .z
 End With
   
 With stG   ' Variabile del tipo "Struttura" ritornata per "Indirizzo"
   Print .x
   Print .Y
   Print .z
 End With
  
End
 

Private Procedure creaso()
 
 File.Save("/tmp/libesterna.c", "struct STRUTTURA_C {" &
           "double x\n;" &
           "double y\n;" &
           "double z;};" &
           "\n\n" &
           "\nstruct STRUTTURA_C * FunzioneEsterna(struct STRUTTURA_C *p) {" &
           "\n\n"
           "   p->x *= 11.11;\n" &
           "   p->y *= 22.22;\n" &
           "   p->z *= 33.33;\n" &
           "   return p;\n}")
  
 Shell "gcc -o /tmp/libesterna.so /tmp/libesterna.c -shared" Wait
  
End