Differenze tra le versioni di "Write ()"
(Una versione intermedia di uno stesso utente non è mostrata) | |||
Riga 4: | Riga 4: | ||
− | Poiché il suo nome è identico al nome della funzione ''Write'' di Gambas, è opportuno dichiararla con ''Extern'' mediante un nome | + | Poiché il suo nome è identico al nome della funzione ''Write'' di Gambas, è opportuno dichiararla con ''Extern'' mediante un nome fittizio, specificando con ''Exec'' il suo nome reale: <SUP>[[[#Note|nota 1]]]</sup> |
Private <FONT Color=#B22222>Extern write_C</font>(__fd As Integer, __buf As Pointer, __n As Long) As Long <FONT Color=#B22222>Exec "write"</font> | Private <FONT Color=#B22222>Extern write_C</font>(__fd As Integer, __buf As Pointer, __n As Long) As Long <FONT Color=#B22222>Exec "write"</font> | ||
Riga 25: | Riga 25: | ||
− | + | Public Sub Main() | |
Dim fd, i As Integer | Dim fd, i As Integer | ||
Riga 31: | Riga 31: | ||
<FONT Color=gray>' ''Viene aperto in scrittura un file di testo:''</font> | <FONT Color=gray>' ''Viene aperto in scrittura un file di testo:''</font> | ||
− | fd = open_C("<FONT Color= | + | fd = open_C("<FONT Color=darkgreen>''/percorso/del/file''</font>", O_WRONLY) |
<FONT Color=gray>' ''Asegna alla variabile "i" il vaore da scrivere nel file:''</font> | <FONT Color=gray>' ''Asegna alla variabile "i" il vaore da scrivere nel file:''</font> | ||
i = 1000 | i = 1000 | ||
− | + | ||
<FONT Color=gray>' ''Scrive nel file, utilizzando il suo "file descriptor" come handle il valore contenuto nella variabile "i", avendo però l'accortezza di passare alla funzione esterna "write()" l'indirizzo di memoria di quella variabile:''</font> | <FONT Color=gray>' ''Scrive nel file, utilizzando il suo "file descriptor" come handle il valore contenuto nella variabile "i", avendo però l'accortezza di passare alla funzione esterna "write()" l'indirizzo di memoria di quella variabile:''</font> | ||
l = <FONT Color=#B22222>write_C</font>(fd, VarPtr(i), SizeOf(TypeOf(i))) | l = <FONT Color=#B22222>write_C</font>(fd, VarPtr(i), SizeOf(TypeOf(i))) | ||
Riga 41: | Riga 41: | ||
close_C(fd) | close_C(fd) | ||
− | + | ||
− | + | End | |
Riga 57: | Riga 57: | ||
− | + | Public Sub Main() | |
Dim fl As File | Dim fl As File | ||
Riga 64: | Riga 64: | ||
Dim l As Long | Dim l As Long | ||
− | fl = Open "<FONT Color= | + | fl = Open "<FONT Color=darkgreen>''/percorso/del/file''</font>" For Write |
<FONT Color=gray>' ''Asegna alla variabile "i" il vaore da scrivere nel file:''</font> | <FONT Color=gray>' ''Asegna alla variabile "i" il vaore da scrivere nel file:''</font> | ||
Riga 75: | Riga 75: | ||
fl.Close | fl.Close | ||
− | + | End | |
− | ==Usare la funzione "write() di C con la funzione "fopen() di C== | + | ==Usare la funzione "write() di C con la funzione "fopen()" di C== |
− | Mostriamo in questo paragrafo una particolarità: l'uso di due funzioni esterne per aprire e scrivere in un file non appartenenti alla stessa famiglia | + | Mostriamo in questo paragrafo una particolarità: l'uso di due funzioni esterne per aprire e scrivere in un file non appartenenti alla stessa famiglia delle funzioni I/O. Nello specifico si utilizzerà la funzione esterna ''write( )'' per scrivere in un file aperto con la funzione esterna "fopen()". |
− | Per aprire in lettura e/o scrittura un file, si utilizzano in modo esclusivo le funzioni | + | Per aprire in lettura e/o scrittura un file, si utilizzano in modo esclusivo le funzioni "open()", "read()" e "write()", oppure le funzioni "fopen()", "fread()" e "fwrite()". La funzione di apertura del file "open()" ritorna un valore di tipo Intero che è il ''file descriptor'' del file aperto e che rappresenta così l'handle per gestire la lettura e/o la scrittura del file medesimo. Se invece si utilizza per l'apertura del file la funzione "fopen()", questa ritorna un ''Puntatore'' al file aperto. Tale Puntatore sarà l'handle per gestire la lettura e/o la scrittura di quel file. Da ciò si può facilmente notare che il file potrà essere letto e/o scritto solo mediante le funzioni appartenenti alla medesima famiglia della funzione con la quale il file è stato aperto. Così, ad esempio, se si apre il file con la funzione "fopen()" non si potranno usare le funzioni "read()" e "write()". |
− | <BR>Esiste, però, la possibilità di utilizzare la funzione | + | <BR>Esiste, però, la possibilità di utilizzare la funzione "fopen()" congiuntamente ed in sinergia con le due funzioni di lettura e di scrittura, rispettivamente "read()" e "write()", che di norma - come abbiamo sopra detto - non sono utilizzabili con la funzione di apertura "fopen()". Sappiamo che la funzione "fopen()" restituisce un Puntatore ad una Struttura, il cui identificatore MACRO è "''FILE'' ", ed è il "''typedef'' " della Struttura ''_IO_FILE'' dichiarata nel file header "''/usr/include/libio.h'' ". |
− | <BR>Non tutti i membri di detta Struttura sono accessibili in un codice scritto inlinguaggio C, in quanto essa viene richiamata nel file header "''stdio.h''" con la MACRO "''FILE''" come un tipo "''opaco''". Fa eccezione il membro chiamato "''_fileno''", e lì dichiarato come "''int''" (Intero), contenente il numero del descrittore del file aperto, al quale si riferisce. Essendo, dunque, tale membro accessibile, sarà possibile leggere il valore ivi contenuto, e che - come già detto - rappresenta il numero identificatore del | + | <BR>Non tutti i membri di detta Struttura sono accessibili in un codice scritto inlinguaggio C, in quanto essa viene richiamata nel file header "''stdio.h'' " con la MACRO "''FILE'' " come un tipo "''opaco'' ". Fa eccezione il membro chiamato "''_fileno''", e lì dichiarato come "''int'' " (Intero), contenente il numero del descrittore del file aperto, al quale si riferisce. Essendo, dunque, tale membro accessibile, sarà possibile leggere il valore ivi contenuto, e che - come già detto - rappresenta il numero identificatore del ''file descriptor'' del file aperto con la funzione "fopen()". Tutto ciò permetterà di utilizzare le funzioni "read()" e "write()" anche su un file aperto con la funzione "fopen()". |
− | Usando tali funzioni in Gambas, poiché nell'area di memoria riservata di detta Struttura il membro in questione, ''__fileno'', è posto al byte di indice 112, si passerà il ''Puntatore'', ritornato dalla funzione esterna | + | Usando tali funzioni in Gambas, poiché nell'area di memoria riservata di detta Struttura il membro in questione, ''__fileno'', è posto al byte di indice 112, si passerà il ''Puntatore'', ritornato dalla funzione esterna "fopen()", al primo argomento della funzione "read()" e/o della funzione "write()", avendo cura di piazzare l'offset nell'area riservata all'indice 112. |
− | Mostriamo un semplice esempio, di un file aperto in " | + | Mostriamo un semplice esempio, di un file aperto in "scrittura" mediante la funzione "fopen()", nel quale si scriverà un valore Intero però - con gli accorgimenti sopra descritti - mediante la funzione "write()". |
Library "libc:6" | Library "libc:6" | ||
Riga 103: | Riga 103: | ||
− | + | Public Sub Main() | |
Dim p1, p2 As Pointer | Dim p1, p2 As Pointer | ||
Riga 109: | Riga 109: | ||
<FONT Color=gray>' ''Apriamo un file di testo in scrittura:''</font> | <FONT Color=gray>' ''Apriamo un file di testo in scrittura:''</font> | ||
− | p1 = fopen("<FONT Color= | + | p1 = fopen("<FONT Color=darkgreen>''/percorso/del/file''</font>", "w") |
<FONT Color=gray>' ''Asegna alla variabile "i" il vaore da scrivere nel file:''</font> | <FONT Color=gray>' ''Asegna alla variabile "i" il vaore da scrivere nel file:''</font> | ||
Riga 123: | Riga 123: | ||
fclose(p1) | fclose(p1) | ||
− | + | End | |
Versione attuale delle 10:52, 13 giu 2024
La funzione write(), dichiarata nel file header /usr/include/unistd.h con la seguente sintassi:
ssize_t write (int __fd, const void *__buf, size_t __n)
scrive nel file, a cui si riferisce il descrittore di file __fd, un numero di byte definito da __n dal buffer puntato da __buf. Essa ritorna il numero di byte scritti, oppure -1 in caso di errore.
Poiché il suo nome è identico al nome della funzione Write di Gambas, è opportuno dichiararla con Extern mediante un nome fittizio, specificando con Exec il suo nome reale: [nota 1]
Private Extern write_C(__fd As Integer, __buf As Pointer, __n As Long) As Long Exec "write"
Mostriamo un esempio pratico:
Library "libc:6" Private Enum O_RDONLY = 0, O_WRONLY, O_RDWR ' int open(const char *__file, int __oflag, ...) ' Open FILE and return a new file descriptor for it. Private Extern open_C(__file As String, __oflag As Integer) As Integer Exec "open" ' ssize_t write (int __fd, const void *__buf, size_t __n) ' Write N bytes of BUF to FD. Private Extern write_C(__fd As Integer, __buf As Pointer, __n As Long) As Long Exec "write" ' int close(int _fd) ' Deallocates the file descriptor indicated by fildes. Private Extern close_C(_fd As Integer) As Integer Exec "close" Public Sub Main() Dim fd, i As Integer Dim l As Long ' Viene aperto in scrittura un file di testo: fd = open_C("/percorso/del/file", O_WRONLY) ' Asegna alla variabile "i" il vaore da scrivere nel file: i = 1000 ' Scrive nel file, utilizzando il suo "file descriptor" come handle il valore contenuto nella variabile "i", avendo però l'accortezza di passare alla funzione esterna "write()" l'indirizzo di memoria di quella variabile: l = write_C(fd, VarPtr(i), SizeOf(TypeOf(i))) If l == -1 Then Error.Raise("Impossibile scrivere nel file !") close_C(fd) End
Indice
Uso della funzione esterna "write()" con la funzione nativa "Open" di Gambas
Nell'esempio precedente abbiamo visto la funzione esterna "write()" scrivere un dato in un file aperto con la funzione esterna open()" di C.
Nel presente paragrafo vedremo sostituire la funzione esterna "open()" di C con la funzione nativa di Gambas "Open", per aprire in scrittura un file. Successivamente all'apertura del file bisognerà passare al primo argomento della funzione esterna "write()" di C il file descriptor del file aperto, utilizzando la Proprietà ".Handle" della variabile di tipo File relativa al file aperto con "Open" di Gambas.
Mostriamo un semplice esempio pratico:
Library "libc:6" ' ssize_t write (int __fd, const void *__buf, size_t __n) ' Write N bytes of BUF to FD. Private Extern write_C(__fd As Integer, __buf As Pointer, __n As Long) As Long Exec "write" Public Sub Main() Dim fl As File Dim p As Pointer Dim i As Integer Dim l As Long fl = Open "/percorso/del/file" For Write ' Asegna alla variabile "i" il vaore da scrivere nel file: i = 100 p = VarPtr(i) l = write_C(fl.Handle, p, SizeOf(TypeOf(i))) If l == 0 Then Error.Raise("Impossibile scrivere nel file !") fl.Close End
Usare la funzione "write() di C con la funzione "fopen()" di C
Mostriamo in questo paragrafo una particolarità: l'uso di due funzioni esterne per aprire e scrivere in un file non appartenenti alla stessa famiglia delle funzioni I/O. Nello specifico si utilizzerà la funzione esterna write( ) per scrivere in un file aperto con la funzione esterna "fopen()".
Per aprire in lettura e/o scrittura un file, si utilizzano in modo esclusivo le funzioni "open()", "read()" e "write()", oppure le funzioni "fopen()", "fread()" e "fwrite()". La funzione di apertura del file "open()" ritorna un valore di tipo Intero che è il file descriptor del file aperto e che rappresenta così l'handle per gestire la lettura e/o la scrittura del file medesimo. Se invece si utilizza per l'apertura del file la funzione "fopen()", questa ritorna un Puntatore al file aperto. Tale Puntatore sarà l'handle per gestire la lettura e/o la scrittura di quel file. Da ciò si può facilmente notare che il file potrà essere letto e/o scritto solo mediante le funzioni appartenenti alla medesima famiglia della funzione con la quale il file è stato aperto. Così, ad esempio, se si apre il file con la funzione "fopen()" non si potranno usare le funzioni "read()" e "write()".
Esiste, però, la possibilità di utilizzare la funzione "fopen()" congiuntamente ed in sinergia con le due funzioni di lettura e di scrittura, rispettivamente "read()" e "write()", che di norma - come abbiamo sopra detto - non sono utilizzabili con la funzione di apertura "fopen()". Sappiamo che la funzione "fopen()" restituisce un Puntatore ad una Struttura, il cui identificatore MACRO è "FILE ", ed è il "typedef " della Struttura _IO_FILE dichiarata nel file header "/usr/include/libio.h ".
Non tutti i membri di detta Struttura sono accessibili in un codice scritto inlinguaggio C, in quanto essa viene richiamata nel file header "stdio.h " con la MACRO "FILE " come un tipo "opaco ". Fa eccezione il membro chiamato "_fileno", e lì dichiarato come "int " (Intero), contenente il numero del descrittore del file aperto, al quale si riferisce. Essendo, dunque, tale membro accessibile, sarà possibile leggere il valore ivi contenuto, e che - come già detto - rappresenta il numero identificatore del file descriptor del file aperto con la funzione "fopen()". Tutto ciò permetterà di utilizzare le funzioni "read()" e "write()" anche su un file aperto con la funzione "fopen()".
Usando tali funzioni in Gambas, poiché nell'area di memoria riservata di detta Struttura il membro in questione, __fileno, è posto al byte di indice 112, si passerà il Puntatore, ritornato dalla funzione esterna "fopen()", al primo argomento della funzione "read()" e/o della funzione "write()", avendo cura di piazzare l'offset nell'area riservata all'indice 112.
Mostriamo un semplice esempio, di un file aperto in "scrittura" mediante la funzione "fopen()", nel quale si scriverà un valore Intero però - con gli accorgimenti sopra descritti - mediante la funzione "write()".
Library "libc:6" ' FILE *fopen (const char *__restrict __filename, const char *__restrict __modes) ' Open a file and create a new stream for it. Private Extern fopen(__filename As String, __modes As String) As Pointer ' ssize_t write (int __fd, const void *__buf, size_t __n) ' Write N bytes of BUF to FD. Private Extern write_C(__fd As Integer, __buf As Pointer, __n As Long) As Long Exec "write" ' int fclose (FILE *__stream) ' Close STREAM. Private Extern fclose(__stream As Pointer) As Integer Public Sub Main() Dim p1, p2 As Pointer Dim i As Integer ' Apriamo un file di testo in scrittura: p1 = fopen("/percorso/del/file", "w") ' Asegna alla variabile "i" il vaore da scrivere nel file: i = 100 p2 = VarPtr(i) Print Int@(p2) ' Scrive nel file descriptor del file due volte il valore presente nella variabile "i" puntata dal Puntatore "p2": write_C(Int@(p1 + 112), p2, SizeOf(gb.Integer)) write_C(Int@(p1 + 112), p2, SizeOf(gb.Integer)) ' Chiude il file precedentemente aperto: fclose(p1) End
Note
[1] Si è visto, però, che se nel corpo del codice la funzione esterna di C, avente un nome simile ad una funzione nativa di Gambas, viene utilizzata con il suo esatto nome, ossia con la lettera iniziale minuscola, essa funziona regolarmente, senza necessità quindi di usare un nome fittizio.