Differenze tra le versioni di "Scrivere una libreria esterna che ritorna una Struttura"
Riga 1: | Riga 1: | ||
− | Di seguito | + | 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