...un altro errore dell'utente
shane_2, che egli estesso rileva successivamente con la frase:
"
i was getting strange values eg.
a struct size of 208 when it was meant to be 128 and for some strange
reason get end of file "
sta nella dichiarazione della sua Struttura chiamata "ID3v1_TAG".
L'utente
shane_2 si aspetta una dimensione di tale Struttura pari a 128 byte, invece
incomprensibilmente - per lui - se ne ritrova 208 byte.
"
Strange", dice lui, ma strano non è. Vediamo perché.
L'errore deriva dalla evidente mancata conoscenza del linguaggio C e dal fatto che in Gambas tutto ciò che è un carattere ASCII viene gestito con il tipo "
String".
Rivediamo infatti la Struttura da lui scritta e dichiarata:
Public Struct ID3v1_TAG '(128 bytes)
Tag[3] As String 'always TAG
Title[30] As String 'title, 30 characters
Artist[30] As String 'artist, 30 characters
Album[30] As String 'album, 30 characters
Year[4] As String 'year, 4 characters
Comment[30] As String 'comment, 30 characters (or 28 if track# included)
Genre As Byte 'genre, 255 for none defined
End Struct
Come è possibile vedere, lui intende inserire in vari membri della Struttura stringhe fino a 30 caratteri. Per fare questo dichiara i relativi membri come vettori di tipo Stringa, ma lo fa dichiarando - più precisamente - per ciascun membro una variabile vettoriale di 30 elementi di tipo "String". In questo modo tenta
maldestramente di emulare una soluzione tipica del C, nel quale per intercettare in quel modo uno o più caratteri vengono utilizzati array di tipo "
char" (il tipo "
char" in Gambas =
Byte).
Shane_2 - abituato al costume Gambas - ritiene di inserire un carattere in ciascun elemento del array di tipo "String" dei membri vettoriali della Struttura. Così lui dichiara array di 30 elementi di tipo Stringa per la corrispondenza 1 elemento stringa = un carattere. ....o meglio: un carattere in un elemento di tipo Stringa del membro vettore. Si ha che occupa 30 * 8 byte di memoria per soli massimo 30 byte occupabili dai caratteri !!!
Inoltre, erroreamente
crede che la dimensione della Struttura sia di 208 Byte, ma questo valore corrisponde probabilmente alla memoria occupata - ...diciamo - di default, di base da un
Oggetto Struttura
Infatti, verificando con il Metodo
Object.SizeOf( ) la Struttura inserendo nell'unico parametro l'identificativo della Struttura medesima, qualunque sia il numero e la tipologia dei membri della Struttura medesima, la sua dimensione sarà sempre 208 byte.
Se, invece, nel parametro del predetto Metodo inseriamo la variabile del tipo di quella Struttura, il conto sale molto su: 1024.
Si ottiene come segue, tenendo conto che in un sistema a 64 bit un tipo "
String" occupa 8 Byte di memoria:
Tag[3] As String 8 byte * 3 = 24 byte occupati
Title[30] As String 8 byte * 30 = 240 byte occupati
Artist[30] As String 8 byte * 30 = 240 byte occupati
Album[30] As String 8 byte * 30 = 240 byte occupati
Year[4] As String 8 byte * 4 = 32 byte occupati
Comment[30] As String 8 byte * 30 = 240 byte occupati
Genre As Byte 1 byte * 1 = 1 byte occupatoTotale
1017 byte occupati
Poiché,
però, la quantità di memoria di una Struttura non può essere diversa da un valore uguale o multiplo alla quantità di memoria occupata dal tipo maggiore presente nella tipologia dei membri della Struttra (nel nostro caso il tipo "String" = 8 byte occupati), si provvede automaticamente all'
allineamento di memoria.
Al riguardo leggetevi questo mio pesantissimo mattone:
http://www.gambas-it.org/wiki/index.php?title=Gestire_con_un_Puntatore_le_Strutture_esternePoiché, dunque, il valore più grande di memoria occupata è quello del tipo "
String" (8 byte), è necessario
allineare la memoria occupata al valore multiplo immediatamente superiore al valore 1017, ossia: 1024.
Pertanto, la reale quantità di memoria occupata da quella Struttura sarà:
1024 byte !
La conferma della legge dell'
allineamento dei byte occupati in memoria dai membri di una Struttura, l'avrete eliminando l'ultimo membro della Struttura dichiarata dall'utente
Shane_2, ossia il Byte che occupa 1 solo byte. ...
stranamente avrete il risultato di 1016 ...che è il valore multiplo inferiore più prossimo a 1024.
Ritorno ora al principio.
Volendo emulare le dichiarazioni tipiche del caso in C come avrebbe dovuto fare ?
Shane_2 avrebbe dovuto cambiare il tipo
String[ ] dei membri vettoriali con il tipo
Byte[ ], e successivamente alla loro valorizzazione leggerli con il loro metodo "
.ToString( )".
Lo so, avrei potuto meravigliarvi con effetti speciali......