Differenze tra le versioni di "Scrivere una libreria esterna che ritorna una Struttura"

Da Gambas-it.org - Wikipedia.
Riga 1: Riga 1:
Di seguito è mostrato un esempio, nel quale la funzione esterna della libreria in C ritorna una ''Struttura''.
+
Di seguito mostriamo alcuni esempi, nei quali la funzione esterna della libreria in C ritorna ''per valore'' una ''Struttura''.
  
  
Riga 41: Riga 41:
 
   
 
   
 
   Print nst.a, String@(nst.b)
 
   Print nst.a, String@(nst.b)
 +
 +
'''End'''
 +
 +
 +
====2° esempio====
 +
In quest'altro esempio nel codice Gambas dell'applicativo non è dichiarata ed usata una ''Struttura'' simile a quella dichiarata in C, ma si opererà sul ''Puntatore'' ottenuto, contenente l'indirizzo di memeoria della Struttura del codice C, per estrarre i valori dei membri della ''Struttura''.
 +
Il codice della libreria esterna in C:
 +
#include <stdlib.h>
 +
 +
 +
struct AAA {
 +
  int i;
 +
  char * p;
 +
  short s;
 +
};
 +
 +
struct AAA a;
 +
 +
 +
struct AAA * Prova() {
 +
 +
  a.i = 0x00444444;
 +
 
 +
  a.p = (char *) malloc(4);
 +
  a.p[0] = 0x0A;
 +
  a.p[1] = 0x0B;
 +
  a.p[2] = 0x0C;
 +
  a.p[3] = 0x0D;
 +
 
 +
  a.s = 0x0400;
 +
 +
  return &a;
 +
 +
}
 +
 +
 +
Codice Gambas:
 +
Private Extern Prova() As Pointer In "/tmp/libreria_C"
 +
 +
 +
'''Public''' Sub Main()
 +
 +
  Dim p, po As Pointer
 +
  Dim st, re As Stream
 +
  Dim j, b As Byte
 +
 
 +
 
 +
  Shell "gcc -o /tmp/libreria_C.so " & Application.Path &/ "libreria_C.c -shared -fPIC" Wait
 +
 
 +
    p = Prova()
 +
    If IsNull(p) Then Error.Raise("Puntatore NULLO !")
 +
 
 +
    st = Memory p For Read
 +
    Print Read #st As Integer
 +
 +
<FONT Color=gray>' ''Posizioniamo il puntatore interno del flusso al byte di indice 8 per gli effetti dell'allineamento, dato che il prossimo valore occupa 8 byte (è un "Puntatore"= 0, 8, 16, 24, 32, ...etc):''</font>
 +
    Seek #st, 8
 +
    Read #st, po
 +
    re = Memory po For Read
 +
    For j = 0 To 3
 +
      Read #re, b
 +
      Print Hex(b, 2)
 +
    Next
 +
    re.Close
 +
 +
  Print Read #st As Short
 +
 +
  st.Close
 
   
 
   
 
  '''End'''
 
  '''End'''

Versione delle 12:24, 14 mag 2015

Di seguito mostriamo alcuni esempi, nei quali la funzione esterna della libreria in C ritorna per valore una Struttura.


Codice della libreria esterna in C:

struct nome_struttura {
  int a;
  char *b;
};

struct nome_struttura variabile_struttura;


struct nome_struttura *prova() {

   variabile_struttura.a = 99;    // Assegna i valori ai membri della Struttura
   variabile_struttura.b = "prova";

   return &variabile_struttura;

}


Codice Gambas:

Public Struct Nome_Struttura
  a As Integer
  b As Pointer
End Struct


Library "/tmp/libprovaC"
Private Extern prova() As Nome_Struttura


Public Sub Main()

 Dim nst As New Nome_Struttura

  Shell "gcc -o /tmp/libprovaC.so " & Application.Path & "/libprovaC.c -shared -fPIC" Wait
 
  nst = prova()

  Print nst.a, String@(nst.b)

End


2° esempio

In quest'altro esempio nel codice Gambas dell'applicativo non è dichiarata ed usata una Struttura simile a quella dichiarata in C, ma si opererà sul Puntatore ottenuto, contenente l'indirizzo di memeoria della Struttura del codice C, per estrarre i valori dei membri della Struttura. Il codice della libreria esterna in C:

#include <stdlib.h>


struct AAA {
  int i;
  char * p;
  short s;
};

struct AAA a;


struct AAA * Prova() {

  a.i = 0x00444444;
 
  a.p = (char *) malloc(4);
  a.p[0] = 0x0A;
  a.p[1] = 0x0B;
  a.p[2] = 0x0C;
  a.p[3] = 0x0D;
 
  a.s = 0x0400;

  return &a;

}


Codice Gambas: Private Extern Prova() As Pointer In "/tmp/libreria_C"


Public Sub Main()

 Dim p, po As Pointer
 Dim st, re As Stream
 Dim j, b As Byte
 
 
  Shell "gcc -o /tmp/libreria_C.so " & Application.Path &/ "libreria_C.c -shared -fPIC" Wait
 
   p = Prova()
   If IsNull(p) Then Error.Raise("Puntatore NULLO !")
  
   st = Memory p For Read
   Print Read #st As Integer

' Posizioniamo il puntatore interno del flusso al byte di indice 8 per gli effetti dell'allineamento, dato che il prossimo valore occupa 8 byte (è un "Puntatore"= 0, 8, 16, 24, 32, ...etc):
   Seek #st, 8
   Read #st, po
   re = Memory po For Read
    For j = 0 To 3
      Read #re, b
      Print Hex(b, 2)
    Next
   re.Close

  Print Read #st As Short

  st.Close

End


Caso in cui la funzione esterna ritorna una Struttura avente tra i suoi membri uno o più vettori di tipo "char"

Codice della libreria esterna in C:

struct nome_struttura {
  char b[4];
  int a;
};

struct nome_struttura variabile_struttura;


struct nome_struttura *prova() {

   variabile_struttura.b[0] = 'p';   //assegna un carattere per ciascun elemento del vettore di tipo "chr"
   variabile_struttura.b[1] = 'e';
   variabile_struttura.b[2] = 'r';
   variabile_struttura.b[3] = 'a';

   variabile_struttura.a = 99;

   return &variabile_struttura;      // ritorna l'indirizzo di "variabile_struttura"

};


Codice Gambas

Se un membro della Struttura, presente nella libreria esterna in C, è dichiarato come un vettore di tipo "char", allora il corrispondente membro della rispettiva Struttura in Gambas potrà essere dichiarato come vettore di tipo Byte[]. I valori di tale vettore di tipo Byte[] potranno essere recuperati, ai fini della ricomposizione dell'intera stringa di caratteri, con il metodo .ToString().

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


Library "/tmp/libprovaC"
Private Extern prova() As Nome_Struttura


Public Sub Main()

 Dim nst As New Nome_Struttura

 Shell "gcc -o /tmp/libprovaC.so " & Application.Path & "/libprovaC.c -shared -fPIC" Wait

 nst = prova()

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

End