Scrivere una libreria esterna che ritorna una Struttura
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