Differenze tra le versioni di "Scrivere una libreria esterna che ritorna un valore attraverso un parametro di una sua funzione"

Da Gambas-it.org - Wikipedia.
 
Riga 10: Riga 10:
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
   
 
   
 
   Dim i1, i2, rit As Integer
 
   Dim i1, i2, rit As Integer
Riga 23: Riga 23:
 
   Print i1, i2, rit
 
   Print i1, i2, rit
 
   
 
   
  '''End'''
+
  End
 
   
 
   
  '''Private''' Procedure Creaso()
+
   
 +
Private Procedure Creaso()
 
    
 
    
 
   File.Save("/tmp/libprovaC.c", "void prova1 (int *a) {\n" &
 
   File.Save("/tmp/libprovaC.c", "void prova1 (int *a) {\n" &
Riga 39: Riga 40:
 
   Shell "gcc -o /tmp/libprovaC.so /tmp/libprovaC.c -shared -fPIC" Wait
 
   Shell "gcc -o /tmp/libprovaC.so /tmp/libprovaC.c -shared -fPIC" Wait
 
   
 
   
  '''End'''
+
  End
 
 
  
  
Riga 49: Riga 49:
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
   
 
   
 
   Dim p As Pointer
 
   Dim p As Pointer
Riga 59: Riga 59:
 
   Print string@(p)
 
   Print string@(p)
 
   
 
   
  '''End'''
+
  End
 +
 
   
 
   
  '''Private''' Procedure Creaso()
+
  Private Procedure Creaso()
 
    
 
    
 
   File.Save("/tmp/libprovaC.c", "char a[4];\n\n" &
 
   File.Save("/tmp/libprovaC.c", "char a[4];\n\n" &
Riga 73: Riga 74:
 
   Shell "gcc -o /tmp/libprovaC.so /tmp/libprovaC.c -shared -fPIC" Wait
 
   Shell "gcc -o /tmp/libprovaC.so /tmp/libprovaC.c -shared -fPIC" Wait
 
   
 
   
  '''End'''
+
  End
 
 
  
  
Riga 89: Riga 89:
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
   
 
   
 
   Dim nst As New Nome_Struttura
 
   Dim nst As New Nome_Struttura
Riga 100: Riga 100:
 
   Print nst.b.ToString()
 
   Print nst.b.ToString()
 
   
 
   
  '''End'''
+
  End
 
   
 
   
  '''Private''' Procedure Creaso()
+
   
 +
Private Procedure Creaso()
 
   
 
   
 
   File.Save("/tmp/libprovaC.c", "struct nome_struttura {\n" &
 
   File.Save("/tmp/libprovaC.c", "struct nome_struttura {\n" &
Riga 118: Riga 119:
 
   Shell "gcc -o /tmp/libprovaC.so /tmp/libprovaC.c -shared -fPIC" Wait
 
   Shell "gcc -o /tmp/libprovaC.so /tmp/libprovaC.c -shared -fPIC" Wait
 
   
 
   
  '''End'''
+
  End
 
 
  
  

Versione attuale delle 19:27, 12 giu 2024

Di seguito vengono mostrati alcuni esempi, nei quali viene recuperato nel codice Gambas un valore da un parametro della funzione che invoca una funzione esterna presente in una libreria da noi scritta in C. Il codice C passerà il valore per indirizzo (ossia per riferimento |1|).


Caso generale in cui viene recuperato un Intero

Codice Gambas che genera anche la libreria esterna in C:

Library "/tmp/libprovaC"

Private Extern prova1(pro As Pointer)
Private Extern prova2(pro As Pointer) As Integer


Public Sub Main()

  Dim i1, i2, rit As Integer

  Creaso()

  prova1(VarPtr(i1))
 
  i2 = 1
  rit = prova2(VarPtr(i2))

  Print i1, i2, rit

End


Private Procedure Creaso()
 
 File.Save("/tmp/libprovaC.c", "void prova1 (int *a) {\n" &
                               "   int t = 99;\n" &
                               "   *a = t;\n}\n\n" &
                               "/* Qualora debba essere passato da Gambas un valore alla libreria C attraverso un parametro di una sua funzione,\ne che sarà dunque utilizzato nella funzione medesima, avremo: */" &
                               "int prova2 (int *a) {\n" &
                               "   int t = 99;\n" &
                               "   *a = *a + t;\n" &
                               "/* Dopo la variabile, da passare attraverso il parametro della funzione, può seguire senza problemi anche altro codice.\nIn questo caso saranno passati sia la varibile attraverso il parametro che il valore terminale di ritorno della funzione: */" &
                               "   return (0);\n}")
 
 Shell "gcc -o /tmp/libprovaC.so /tmp/libprovaC.c -shared -fPIC" Wait

End


Caso in cui viene recuperato un Vettore di tipo "char"

Codice Gambas che genera anche la libreria esterna in C:

Library "/tmp/libprovaC"
Private Extern prova(po As Pointer)


Public Sub Main()

 Dim p As Pointer

 Creaso()

 prova(VarPtr(p))

 Print string@(p)

End


Private Procedure Creaso()
 
 File.Save("/tmp/libprovaC.c", "char a[4];\n\n" &
                               "void prova(char *b[4]) {   // oppure:  void prova(char *b[]) {\n" &
                               "   a[0] = 'p';   // assegna un carattere per ciascun elemento del vettore di tipo 'chr'\n" &
                               "   a[1] = 'e';\n" &
                               "   a[2] = 'r';\n" &
                               "   a[3] = 'a';\n\n" &
                               "   *b = a;\n}")
 
 Shell "gcc -o /tmp/libprovaC.so /tmp/libprovaC.c -shared -fPIC" Wait

End


Caso in cui viene recuperata una Struttura

Codice Gambas che genera anche la libreria esterna in C:

Public Struct Nome_Struttura
  a As Integer
  b[4] As Byte
End Struct


Library "/tmp/libprovaC"
Private Extern prova(nomenStru as Nome_Struttura)


Public Sub Main()

 Dim nst As New Nome_Struttura

 Creaso()

 prova(nst)

 Print nst.a
 Print nst.b.ToString()

End


Private Procedure Creaso()

 File.Save("/tmp/libprovaC.c", "struct nome_struttura {\n" &
                               "   int a;\n" &
                               "   char b[4];\n};\n\n" &
                               "struct nome_struttura variabile_struttura;\n\n" &
                               "void prova(struct nome_struttura *p) {\n" &
                               "   variabile_struttura.a = 99;   // assegna un valore intero alla struttura\n\n" &
                               "   variabile_struttura.b[0] = 'p'; // assegna un carattere per ciascun elemento del vettore di tipo 'chr'\n" &
                               "   variabile_struttura.b[1] = 'e';\n" &
                               "   variabile_struttura.b[2] = 'r';\n" &
                               "   variabile_struttura.b[3] = 'a';\n\n" &
                               "   *p = variabile_struttura;\n}")
 
 Shell "gcc -o /tmp/libprovaC.so /tmp/libprovaC.c -shared -fPIC" Wait

End


Note

[1] Il passaggio di valori per riferimento (o anche detto per indirizzo) prevede che vengano scritti valori di ritorno nelle variabili stesse della funzione chiamante. Viene, cioè, modificato il valore della variabile medesima passata dalla funzione chiamante.