Differenze tra le versioni di "Scrivere una libreria esterna che ritorna un valore attraverso un parametro di una sua funzione"
Da Gambas-it.org - Wikipedia.
(3 versioni intermedie di uno stesso utente non sono mostrate) | |||
Riga 1: | Riga 1: | ||
− | Di seguito vengono mostrati alcuni esempi, nei quali viene recuperato nel codice Gambas un valore da un parametro della funzione che invoca una funzione esterna presente in una libreria da noi scritta in C. Il codice C passerà il valore ''per indirizzo''. | + | Di seguito vengono mostrati alcuni esempi, nei quali viene recuperato nel codice Gambas un valore da un parametro della funzione che invoca una funzione esterna presente in una libreria da noi scritta in C. Il codice C passerà il valore ''per indirizzo'' (ossia per ''riferimento'' |[[#Note|1]]|). |
===Caso generale in cui viene recuperato un ''Intero''=== | ===Caso generale in cui viene recuperato un ''Intero''=== | ||
− | Codice | + | Codice Gambas che genera anche la libreria esterna in C: |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
Library "/tmp/libprovaC" | Library "/tmp/libprovaC" | ||
Private Extern prova1(pro As Pointer) | Private Extern prova1(pro As Pointer) | ||
− | Private Extern prova2(pro As Pointer) | + | Private Extern prova2(pro As Pointer) As Integer |
'''Public''' Sub Main() | '''Public''' Sub Main() | ||
− | + | Dim i1, i2, rit As Integer | |
− | + | Creaso() | |
prova1(VarPtr(i1)) | prova1(VarPtr(i1)) | ||
i2 = 1 | i2 = 1 | ||
− | prova2(VarPtr(i2)) | + | rit = prova2(VarPtr(i2)) |
− | Print i1, i2 | + | Print i1, i2, rit |
'''End''' | '''End''' | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | '''Private''' Procedure Creaso() | ||
+ | |||
+ | File.Save("/tmp/libprovaC.c", "void prova1 (int *a) {\n" & | ||
+ | " int t = 99;\n" & | ||
+ | " *a = t;\n}\n\n" & | ||
+ | "<FONT color=blue>/* Qualora debba essere passato da Gambas un valore alla libreria C attraverso un parametro di una sua funzione,\ne che sarà dunque utilizzato nella funzione medesima, avremo: */</font>" & | ||
+ | "int prova2 (int *a) {\n" & | ||
+ | " int t = 99;\n" & | ||
+ | " *a = *a + t;\n" & | ||
+ | "<FONT color=blue>/* Dopo la variabile, da passare attraverso il parametro della funzione, può seguire senza problemi anche altro codice.\nIn questo caso saranno passati sia la varibile attraverso il parametro che il valore terminale di ritorno della funzione: */</font>" & | ||
+ | " return (0);\n}") | ||
+ | |||
+ | Shell "gcc -o /tmp/libprovaC.so /tmp/libprovaC.c -shared -fPIC" Wait | ||
− | + | '''End''' | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | Codice Gambas: | + | ===Caso in cui viene recuperato un Vettore di tipo "char"=== |
+ | Codice Gambas che genera anche la libreria esterna in C: | ||
Library "/tmp/libprovaC" | Library "/tmp/libprovaC" | ||
Private Extern prova(po As Pointer) | Private Extern prova(po As Pointer) | ||
Riga 74: | Riga 53: | ||
Dim p As Pointer | Dim p As Pointer | ||
− | + | Creaso() | |
prova(VarPtr(p)) | prova(VarPtr(p)) | ||
Riga 81: | Riga 60: | ||
'''End''' | '''End''' | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | '''Private''' Procedure Creaso() | ||
+ | |||
+ | File.Save("/tmp/libprovaC.c", "char a[4];\n\n" & | ||
+ | "void prova(char *b[4]) { <FONT color=blue>// oppure: void prova(char *b[]) {</font>\n" & | ||
+ | " a[0] = 'p'; <FONT color=blue>// assegna un carattere per ciascun elemento del vettore di tipo 'chr'</font>\n" & | ||
+ | " a[1] = 'e';\n" & | ||
+ | " a[2] = 'r';\n" & | ||
+ | " a[3] = 'a';\n\n" & | ||
+ | " *b = a;\n}") | ||
+ | |||
+ | Shell "gcc -o /tmp/libprovaC.so /tmp/libprovaC.c -shared -fPIC" Wait | ||
− | + | '''End''' | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | Codice Gambas: | + | ===Caso in cui viene recuperata una Struttura=== |
+ | Codice Gambas che genera anche la libreria esterna in C: | ||
Public Struct Nome_Struttura | Public Struct Nome_Struttura | ||
a As Integer | a As Integer | ||
Riga 125: | Riga 93: | ||
Dim nst As New Nome_Struttura | Dim nst As New Nome_Struttura | ||
− | + | Creaso() | |
prova(nst) | prova(nst) | ||
Riga 133: | Riga 101: | ||
'''End''' | '''End''' | ||
+ | |||
+ | '''Private''' Procedure Creaso() | ||
+ | |||
+ | File.Save("/tmp/libprovaC.c", "struct nome_struttura {\n" & | ||
+ | " int a;\n" & | ||
+ | " char b[4];\n};\n\n" & | ||
+ | "struct nome_struttura variabile_struttura;\n\n" & | ||
+ | "void prova(struct nome_struttura *p) {\n" & | ||
+ | " variabile_struttura.a = 99; <FONT color=blue>// assegna un valore intero alla struttura</font>\n\n" & | ||
+ | " variabile_struttura.b[0] = 'p'; <FONT color=blue>// assegna un carattere per ciascun elemento del vettore di tipo 'chr'</font>\n" & | ||
+ | " variabile_struttura.b[1] = 'e';\n" & | ||
+ | " variabile_struttura.b[2] = 'r';\n" & | ||
+ | " variabile_struttura.b[3] = 'a';\n\n" & | ||
+ | " *p = variabile_struttura;\n}") | ||
+ | |||
+ | Shell "gcc -o /tmp/libprovaC.so /tmp/libprovaC.c -shared -fPIC" Wait | ||
+ | |||
+ | '''End''' | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | =Note= | ||
+ | [1] Il passaggio di valori per ''riferimento'' (o anche detto per ''indirizzo'') prevede che vengano scritti valori di ritorno nelle variabili stesse della funzione chiamante. Viene, cioè, modificato il valore della variabile medesima passata dalla funzione chiamante. |
Versione delle 19:17, 18 ago 2022
Di seguito vengono mostrati alcuni esempi, nei quali viene recuperato nel codice Gambas un valore da un parametro della funzione che invoca una funzione esterna presente in una libreria da noi scritta in C. Il codice C passerà il valore per indirizzo (ossia per riferimento |1|).
Indice
Caso generale in cui viene recuperato un Intero
Codice Gambas che genera anche la libreria esterna in C:
Library "/tmp/libprovaC" Private Extern prova1(pro As Pointer) Private Extern prova2(pro As Pointer) As Integer Public Sub Main() Dim i1, i2, rit As Integer Creaso() prova1(VarPtr(i1)) i2 = 1 rit = prova2(VarPtr(i2)) Print i1, i2, rit End Private Procedure Creaso() File.Save("/tmp/libprovaC.c", "void prova1 (int *a) {\n" & " int t = 99;\n" & " *a = t;\n}\n\n" & "/* Qualora debba essere passato da Gambas un valore alla libreria C attraverso un parametro di una sua funzione,\ne che sarà dunque utilizzato nella funzione medesima, avremo: */" & "int prova2 (int *a) {\n" & " int t = 99;\n" & " *a = *a + t;\n" & "/* Dopo la variabile, da passare attraverso il parametro della funzione, può seguire senza problemi anche altro codice.\nIn questo caso saranno passati sia la varibile attraverso il parametro che il valore terminale di ritorno della funzione: */" & " return (0);\n}") Shell "gcc -o /tmp/libprovaC.so /tmp/libprovaC.c -shared -fPIC" Wait End
Caso in cui viene recuperato un Vettore di tipo "char"
Codice Gambas che genera anche la libreria esterna in C:
Library "/tmp/libprovaC" Private Extern prova(po As Pointer) Public Sub Main() Dim p As Pointer Creaso() prova(VarPtr(p)) Print string@(p) End Private Procedure Creaso() File.Save("/tmp/libprovaC.c", "char a[4];\n\n" & "void prova(char *b[4]) { // oppure: void prova(char *b[]) {\n" & " a[0] = 'p'; // assegna un carattere per ciascun elemento del vettore di tipo 'chr'\n" & " a[1] = 'e';\n" & " a[2] = 'r';\n" & " a[3] = 'a';\n\n" & " *b = a;\n}") Shell "gcc -o /tmp/libprovaC.so /tmp/libprovaC.c -shared -fPIC" Wait End
Caso in cui viene recuperata una Struttura
Codice Gambas che genera anche la libreria esterna in C:
Public Struct Nome_Struttura a As Integer b[4] As Byte End Struct Library "/tmp/libprovaC" Private Extern prova(nomenStru as Nome_Struttura) Public Sub Main() Dim nst As New Nome_Struttura Creaso() prova(nst) Print nst.a Print nst.b.ToString() End Private Procedure Creaso() File.Save("/tmp/libprovaC.c", "struct nome_struttura {\n" & " int a;\n" & " char b[4];\n};\n\n" & "struct nome_struttura variabile_struttura;\n\n" & "void prova(struct nome_struttura *p) {\n" & " variabile_struttura.a = 99; // assegna un valore intero alla struttura\n\n" & " variabile_struttura.b[0] = 'p'; // assegna un carattere per ciascun elemento del vettore di tipo 'chr'\n" & " variabile_struttura.b[1] = 'e';\n" & " variabile_struttura.b[2] = 'r';\n" & " variabile_struttura.b[3] = 'a';\n\n" & " *p = variabile_struttura;\n}") Shell "gcc -o /tmp/libprovaC.so /tmp/libprovaC.c -shared -fPIC" Wait End
Note
[1] Il passaggio di valori per riferimento (o anche detto per indirizzo) prevede che vengano scritti valori di ritorno nelle variabili stesse della funzione chiamante. Viene, cioè, modificato il valore della variabile medesima passata dalla funzione chiamante.