Caricare i dati di un vettore scritto in C in un vettore di un'applicazione Gambas

Da Gambas-it.org - Wikipedia.

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à copiare - qualora siano presenti anche altri simboli e risorse - la variabile vettoriale del sorgente C in un nuovo sorgente scritto sempre in linguaggio C, aggiungendovi anche una semplice funzione che restituisca la dimensione del vettore (ossia la quantità di byte/valori contenuti) e finalmente trasformata in un'apposita libreria dinamica condivisa .so da richiamare nell'applicazione Gambas.


Mostriamo di seguito un semplice esempio.

Poniamo il caso che i dati della variabile vettoriale del codice sorgente C siano i seguenti:

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à 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.

Public Sub Main()

 Dim p As Pointer
 Dim i As Integer
 Dim bb As New Byte[]
 
' Generiamo l'apposita libreria dinamica condivisa .so:
  CreaSo()

' Puntiamo all'area di memoria della variabile vettoriale ora contenuta dall'apposita libreria dinamica .so:
  p = System.GetExternSymbol("/tmp/Lib_C", "vettore_C")
  If IsNull(p) Then Error.Raise("Puntatore NULLO !")
  
' Leggiamo dall'area di memoria della variabile vettoriale contenuta dallalibreria dinamica .so, fino a che il valore letto non sia zero
' ed assegnamo i valori, così letti, alla variabile vettoriale dell'applicazione Gambas:
  While Byte@(p + i) > 0
    bb.Push(Byte@(p + i))
    Inc i
  Wend
     
' Vediamo semplicemente in console la quantità di elementi del vettore istanziati:
  Print bb.Count

End
 

Private Procedure CreaSo()

  File.Save("/tmp/Lib_C.c", "unsigned char vettore_C[] = {" &
                            "0x70, 0x7d, 0x86, 0x9a, 0xac, 0xb8, 0xbc, 0xc5," &
                            "\n0x9d, 0xba, 0xd5, 0xe9, 0xf7, 0xfd, 0xfd, 0xf2\n};")
   
  Shell "gcc -o /tmp/Lib_C.so /tmp/Lib_C.c -shared" Wait
  
End