Differenze tra le versioni di "Caricare i dati di un vettore scritto in C in un vettore di un'applicazione Gambas"

Da Gambas-it.org - Wikipedia.
 
(3 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
Se si ha un codice sorgente, scritto in C, nel quale vi è una variabile vettoriale ''globale'' istanziata con dei valori, per assumere e caricare tali valori in una variabile vettoriale di un'applicazione Gambas senza che vengano ricopiati manualmente nel codice sorgente di tale applicazione, si potrà generare dal codice sorgente, scritto in C, un'apposita libreria dinamica condivisa .so da richiamare nell'applicazione Gambas.
+
Se si ha un codice sorgente, scritto in C, nel quale vi è una variabile vettoriale ''globale'' istanziata con dei valori, per assumere e caricare tali valori in una variabile vettoriale di un'applicazione Gambas senza che vengano ricopiati manualmente nel codice sorgente di tale applicazione, si potrà generare dal codice sorgente, scritto in C, un'apposita libreria condivisa .so da richiamare nell'applicazione Gambas.
  
  
Riga 10: Riga 10:
 
  };
 
  };
  
Dal codice sorgente, nel quale è presente il predetto vettore, si genererà a parte - come già detto - un'apposita libreria esterna dinamica condivisa .so . L'area di memoria del vettore, poi, sarà puntata in Gambas con il meotodo ''GetExternSymbol()'' della Classe ''System''. Ottenuto il relativo ''Puntatore'' a quell'area di memoria, poiché nel nostro caso non esistono valori uguali a zero, si leggerà all'interno dell'area medesima sino a quando non si giungerà al primo valore pari a zero, che rappresenta così l'uscita dall'area di memoria del vettore. Ad ogni modo, se si conosce (come nel nostro esempio) la quantità di elementi costituenti l'array del sorgente C, sarà ovviamente molto agevole leggere tutti i valori contenuti, utilizzando un ciclo ''For...Next'' .
+
Dal codice sorgente, nel quale è presente il predetto vettore, si genererà a parte - come già detto - un'apposita libreria esterna dinamica condivisa .so . L'area di memoria del vettore, poi, sarà puntata in Gambas con il Metodo "GetExternSymbol()" della Classe ''System''. Ottenuto il relativo ''Puntatore'' a quell'area di memoria, poiché nel nostro caso non esistono valori uguali a zero, si leggerà all'interno dell'area medesima sino a quando non si giungerà al primo valore pari a zero, che rappresenta così l'uscita dall'area di memoria del vettore. Ad ogni modo, se si conosce (come nel nostro esempio) la quantità di elementi costituenti l'array del sorgente C, sarà ovviamente molto agevole leggere tutti i valori contenuti, utilizzando un ciclo ''For...Next''.
<BR>Poniamo il caso che la libreria esterna .so, generata, si chiami Lib_C.so.
+
<BR>Poniamo il caso che la libreria esterna condivisa .so, generata, si chiami Lib_C.so.
  '''Public''' Sub Main()
+
  Public Sub Main()
 
   
 
   
 
   Dim p As Pointer
 
   Dim p As Pointer
 
   Dim i As Integer
 
   Dim i As Integer
 
   Dim bb As New Byte[]
 
   Dim bb As New Byte[]
 +
 +
<FONT Color=gray>' ''Punta all'area di memoria della variabile vettoriale ora contenuta dall'apposita libreria dinamica .so:''</font>
 +
  p = System.GetExternSymbol("<FONT Color=gray>''/percorso/della/libreria/esterna/Lib_C''</font>", "vettore_C")
 +
  If p == 0 Then Error.Raise("Puntatore NULLO !")
 
    
 
    
  <FONT Color=gray>' ''Puntiamo all'area di memoria della variabile vettoriale ora contenuta dall'apposita libreria dinamica .so:''</font>
+
  <FONT Color=gray>' ''Legge dall'area di memoria della variabile vettoriale contenuta dalla libreria dinamica .so, fino a che il valore letto non sia zero e assegniamo i valori, così letti, alla variabile vettoriale dell'applicazione Gambas:''</font>
  p = System.GetExternSymbol("''/percorso/della/libreria/esterna/Lib_C", "vettore_C")
+
  While Byte@(p + i) > 0            <FONT Color=gray>' oppure nel nostro caso: For i = 0 To 15</font>
  If IsNull(p) Then Error.Raise("Puntatore NULLO !")
+
    bb.Push(Byte@(p + i))            <FONT Color=gray>'                          bb.Push(Byte@(p + i))</font>
 
+
    Inc i                            <FONT Color=gray>'                        Next</font>
<FONT Color=gray>' ''Leggiamo dall'area di memoria della variabile vettoriale contenuta dallalibreria dinamica .so, fino a che il valore letto non sia zero''
+
  Wend
' ''ed assegnamo i valori, così letti, alla variabile vettoriale dell'applicazione Gambas:''</font>
 
  While Byte@(p + i) > 0            <FONT Color=gray>' oppure nel nostro caso: For i = 0 To 15</font>
 
    bb.Push(Byte@(p + i))            <FONT Color=gray>'                          bb.Push(Byte@(p + i))</font>
 
    Inc i                            <FONT Color=gray>'                        Next</font>
 
  Wend
 
 
        
 
        
  <FONT Color=gray>' ''Vediamo semplicemente in console la quantità di elementi del vettore istanziati:''</font>
+
  <FONT Color=gray>' ''Mostra semplicemente in console la quantità di elementi del vettore istanziati:''</font>
  Print bb.Count
+
  Print bb.Count
 
   
 
   
  '''End'''
+
  End
  
  
 +
Nel caso in cui, invece, la dichiarazione e la definizione dell'array sia presente in un file ''header'' .h, allora si potrà creare un file sorgente in C ove sia posta la Direttiva ''#include'' con il percorso del predetto file ''header'', e sia inserita anche la dichiarazione (come globale) del vettore che deve essere richiamato.
  
Nel caso in cui, invece, la dichiarazione e la definizione dell'array sia presente in un file ''header'' .h, allora si potrà creare un file sorgente in C ove sia posta la direttiva ''#include'' con il percorso del predetto file ''header'', e sia inserita anche la dichiarazione (come globale) del vettore che deve essere richiamato.
+
Il codice Gambas, nel quale può essere creata l'apposita libreria esterna .so, sarà il seguente:
 
+
Public Sub Main()
Poi il codice Gambas sarà il seguente:
 
  '''Public''' Sub Main()
 
 
   
 
   
 
   Dim p As Pointer
 
   Dim p As Pointer
Riga 45: Riga 43:
 
   Dim bb As New Byte[]
 
   Dim bb As New Byte[]
 
   
 
   
  CreaSo()
+
  CreaSo()
 
+
 
  <FONT Color=gray>' ''Puntiamo all'area di memoria della variabile vettoriale ora contenuta dall'apposita libreria dinamica .so:''</font>
+
  <FONT Color=gray>' ''Punta all'area di memoria della variabile vettoriale ora contenuta dall'apposita libreria dinamica .so:''</font>
  p = System.GetExternSymbol("''/percorso/della/libreria/esterna/Lib_C", "vettore_C")
+
  p = System.GetExternSymbol("<FONT Color=gray>''/percorso/della/libreria/esterna/Lib_C''</font>", "vettore_C")
  If IsNull(p) Then Error.Raise("Puntatore NULLO !")
+
  If p == 0 Then Error.Raise("Puntatore NULLO !")
 
+
 
  <FONT Color=gray>' ''Leggiamo dall'area di memoria della variabile vettoriale contenuta dallalibreria dinamica .so, fino a che il valore letto non sia zero''
+
  <FONT Color=gray>' ''Legge dall'area di memoria della variabile vettoriale contenuta dalla libreria condivisa .so, fino a che il valore letto non sia zero e assegniamo i valori, così letti, alla variabile vettoriale dell'applicazione Gambas:''</font>
' ''ed assegnamo i valori, così letti, alla variabile vettoriale dell'applicazione Gambas:''</font>
+
  While Byte@(p + i) > 0            <FONT Color=gray>' oppure nel nostro caso: For i = 0 To 15</font>
  While Byte@(p + i) > 0            <FONT Color=gray>' oppure nel nostro caso: For i = 0 To 15</font>
+
    bb.Push(Byte@(p + i))            <FONT Color=gray>'                          bb.Push(Byte@(p + i))</font>
    bb.Push(Byte@(p + i))            <FONT Color=gray>'                          bb.Push(Byte@(p + i))</font>
+
    Inc i                            <FONT Color=gray>'                        Next</font>
    Inc i                            <FONT Color=gray>'                        Next</font>
+
  Wend
  Wend
+
   
     
 
 
  <FONT Color=gray>' ''Vediamo semplicemente in console la quantità di elementi del vettore istanziati:''</font>
 
  <FONT Color=gray>' ''Vediamo semplicemente in console la quantità di elementi del vettore istanziati:''</font>
  Print bb.Count
+
  Print bb.Count
 
   
 
   
  '''End'''
+
  End
 
   
 
   
'''Private''' Procedure CreaSo()
 
 
   
 
   
  File.Save("''/percorso/del/file/sorgente/della/libreria''", "#include <''/percorso/del/file/header.h>''" &
+
Private Procedure CreaSo()
                            "\n\nunsigned char vettore_C[];")
+
 +
  File.Save("<FONT Color=gray>''/percorso/del/file/sorgente/della/libreria''</font>", "#include <<FONT Color=gray>''/percorso/del/file/header.h>''</font>\n\n" &
 +
                                                          "   unsigned char vettore_C[];")
 
      
 
      
  Shell "gcc -o ''/percorso/della/libreria/esterna.so'' ''/percorso/del/file/sorgente/della/libreria/esterna.c'' -shared" Wait
+
  Shell "gcc -o <FONT Color=gray>''/percorso/della/libreria/esterna.so''</font> <FONT Color=gray>''/percorso/del/file/sorgente/della/libreria/esterna.c''</font> -shared" Wait
 
+
  '''End'''
+
  End

Versione attuale delle 17:14, 12 lug 2023

Se si ha un codice sorgente, scritto in C, nel quale vi è una variabile vettoriale globale istanziata con dei valori, per assumere e caricare tali valori in una variabile vettoriale di un'applicazione Gambas senza che vengano ricopiati manualmente nel codice sorgente di tale applicazione, si potrà generare dal codice sorgente, scritto in C, un'apposita libreria condivisa .so da richiamare nell'applicazione Gambas.


Mostriamo di seguito un semplice esempio.

Poniamo il caso che la variabile vettoriale del codice sorgente C con i suoi valori contenuti sia la seguente:

unsigned char vettore_C[] = {
   0x70, 0x7d, 0x86, 0x9a, 0xac, 0xb8, 0xbc, 0xc5,
   0x9d, 0xba, 0xd5, 0xe9, 0xf7, 0xfd, 0xfd, 0xf2
};

Dal codice sorgente, nel quale è presente il predetto vettore, si genererà a parte - come già detto - un'apposita libreria esterna dinamica condivisa .so . L'area di memoria del vettore, poi, sarà puntata in Gambas con il Metodo "GetExternSymbol()" della Classe System. Ottenuto il relativo Puntatore a quell'area di memoria, poiché nel nostro caso non esistono valori uguali a zero, si leggerà all'interno dell'area medesima sino a quando non si giungerà al primo valore pari a zero, che rappresenta così l'uscita dall'area di memoria del vettore. Ad ogni modo, se si conosce (come nel nostro esempio) la quantità di elementi costituenti l'array del sorgente C, sarà ovviamente molto agevole leggere tutti i valori contenuti, utilizzando un ciclo For...Next.
Poniamo il caso che la libreria esterna condivisa .so, generata, si chiami Lib_C.so.

Public Sub Main()

 Dim p As Pointer
 Dim i As Integer
 Dim bb As New Byte[]

' Punta all'area di memoria della variabile vettoriale ora contenuta dall'apposita libreria dinamica .so:
 p = System.GetExternSymbol("/percorso/della/libreria/esterna/Lib_C", "vettore_C")
 If p == 0 Then Error.Raise("Puntatore NULLO !")
  
' Legge dall'area di memoria della variabile vettoriale contenuta dalla libreria dinamica .so, fino a che il valore letto non sia zero e assegniamo i valori, così letti, alla variabile vettoriale dell'applicazione Gambas:
 While Byte@(p + i) > 0             ' oppure nel nostro caso: For i = 0 To 15
   bb.Push(Byte@(p + i))            '                           bb.Push(Byte@(p + i))
   Inc i                            '                         Next
 Wend
     
' Mostra semplicemente in console la quantità di elementi del vettore istanziati:
 Print bb.Count

End


Nel caso in cui, invece, la dichiarazione e la definizione dell'array sia presente in un file header .h, allora si potrà creare un file sorgente in C ove sia posta la Direttiva #include con il percorso del predetto file header, e sia inserita anche la dichiarazione (come globale) del vettore che deve essere richiamato.

Il codice Gambas, nel quale può essere creata l'apposita libreria esterna .so, sarà il seguente:

Public Sub Main()

 Dim p As Pointer
 Dim i As Integer
 Dim bb As New Byte[]

 CreaSo()
 
' Punta all'area di memoria della variabile vettoriale ora contenuta dall'apposita libreria dinamica .so:
 p = System.GetExternSymbol("/percorso/della/libreria/esterna/Lib_C", "vettore_C")
 If p == 0 Then Error.Raise("Puntatore NULLO !")
 
' Legge dall'area di memoria della variabile vettoriale contenuta dalla libreria condivisa .so, fino a che il valore letto non sia zero e assegniamo i valori, così letti, alla variabile vettoriale dell'applicazione Gambas:
 While Byte@(p + i) > 0             ' oppure nel nostro caso: For i = 0 To 15
   bb.Push(Byte@(p + i))            '                           bb.Push(Byte@(p + i))
   Inc i                            '                         Next
 Wend
    
' Vediamo semplicemente in console la quantità di elementi del vettore istanziati:
 Print bb.Count

End


Private Procedure CreaSo()

 File.Save("/percorso/del/file/sorgente/della/libreria", "#include </percorso/del/file/header.h>\n\n" &
                                                         "   unsigned char vettore_C[];")
   
 Shell "gcc -o /percorso/della/libreria/esterna.so /percorso/del/file/sorgente/della/libreria/esterna.c -shared" Wait

End