Assegnare un valore ad una Struttura di una libreria esterna scrivendo con i Memory Stream nella sua area di memoria

Da Gambas-it.org - Wikipedia.

E' possibile passare un valore ad una Struttura, presente nel codice di una libreria esterna, scrivendo con i Memory Stream direttamente all'interno della sua area di memoria il cui indirizzo è contenuto da un puntatore. L'attribuzione del valore ad uno o più membri di detta Struttura non avverrà nel modo consueto attraverso l'assegnazione del valore Variabile_Struttura.Membro = valore, bensì andando a manipolare internamente all'area di memoria appartenente alla Struttura medesima.


Mostriamo un semplice esempio, in cui abbiamo una libreria esterna creata per l'occasione da noi, nella quale è presente una funzione che sarà chiamata più volte dal programma principale Gambas ed alla quale verrà modificato, ad ogni chiamata, il primo membro di tipo Char della Struttura presente nella libreria medesima:

#include <stdio.h>
#include <unistd.h>

struct AAA {
   char c;
   int short s;
   int short s2;
   int i;
};

struct AAA as;

int n;

struct AAA * Prova() {

/* Nella prima chiamata della funzione esterna, il primo membro avrà il valore del carattere "A": */
   if (n==0) as.c = 'A';
    
/* Assegnamo i valori agli altri membri: */
   as.s = 888;
   as.s2 = 888;
   as.i = 305419896;

   ++n;

/* Mostriamo l'attuale valore assegnato al primo membro - di tipo "Char" della Struttura: */
   printf("%c\n", as.c);

/* Passiamo l'indirizzo di memoria della Struttura: */
   return &as;

}

Tale libreria esterna sarà posta in un qualunque percorso, ed ovviamente in quel percorso dovrà essere richiamata poi dal programm Gambas.


Il programma principale Gambas sarà il seguente:

Private Extern Prova() As Pointer In "/tmp/libreria_esterna"


Public Sub Main()

 Dim p As Pointer
 Dim st As Stream
 Dim b, j, k As Byte

  Shell "gcc -o /tmp/libreria_esterna.so /tmp/libreria_esterna.c -shared -fPIC" Wait
 
' Invochiamo la funzione esterna e ne raccoglimo con un "Puntatore" l'indirizzo di memoria della Strttura esterna passata dalla funzione medesima:
  p = Prova()

' Generiamo lo "Stream" in lettura e scrittura:
  st = Memory p For Read Write

' Andiamo a leggere nell'area di memoria della Struttura esterna, per vedere i valori "iniziali" della Struttura esterna":
   For j = 0 To 15
     Read #st, b
     Print j, b, Hex(b, 2)
   Next
   
' Scriviamo il nuovo valore in un byte preciso dell'area di memoria dela Struttura esterna":
   For k = 0 To 9
   Seek #st, 0
   Write #st, 65 + k As Byte

 Print
 Print

' Andiamo a leggere nel 1° byte (indice 0) dell'area di memoria della Struttura esterna, per vedere il nuovo valore del primo membro di tipo "Char":
  p = Prova()
  Seek #st, 0
  Read #st, b
  Print b, Hex(b, 2)
    
  Next
 
 
 st.Close

End