Come è noto, Gambas riguardo ai tipi di dati deficita un po' rispetto alla disponibilità offerta dal C.
Ad esempio in Gambas non esistono lo Short, l'Integer e il Long "
senza segno".
...non esiste neppure il Byte "
con segno".
Infatti, come sappiamo il tipo "Byte" è in grado di
rappresentare numeri che vanno da 0 fino a 255 (per un complessivo di 256 valori rappresentabili).
In C il suo corrispondente "
char" è disponibile sia nella modalità "senza segno" (come il "Byte" di Gambas) che in quella "
con segno", capace di
rappresentare numeri che vanno da
-127 a +127.
Solitamente in Gambas noi risolviamo agevolmente l'assenza del tipo Byte "
con segno" usando un tipo di dati superiore (ad esempio con lo Short).
Ciò può, però, creare problemi quando si deve procedere ad una lettura di
un solo byte cruda e diretta di un'area di memoria allocata, puntata da un Puntatore, oppure quando si ottiene un valore analogo (di
un solo byte) da una funzione esterna, che però deve essere
rappresentato in negativo.
Mi spiego meglio: ottengo il valore 222 (&hDE), ma deve essere poi ad esempio
rappresentato e
visualizzato in console come -34.
Mostro un codice pratico di quel che ho detto:
' void scrivechar(char * po)
Private Extern scrivechar(po As Pointer) In "/tmp/libbyte"
Public Sub Main()
Dim p As Pointer
p = Alloc(SizeOf(gb.Byte), 2)
Creaso()
' Passa alla funzione esterna l'area, sopra allocata, puntata dalla variabile di tipo Puntatore "p",
' affinché tale funzione esterna vi scriva un valore che occupi un solo byte (char) di memoria:
scrivechar(p)
' Dereferenzia il Puntatore, per ottenere il valore scritto dal codice C.
' Sottrae 256 al valore ritornato, per ottenere lo speculare negativo.
Print "\nDa Gambas: "; Byte@(p) - 256
Free(p)
End
Private Procedure creaso()
File.Save("/tmp/libbyte.c", "#include <stdio.h>\n"
"void scrivechar(char * po) {\n"
" *po = 222;\n"
" printf(\"Dal C: %d\\n\", *po);\n}")
Shell "gcc -o /tmp/libbyte.so /tmp/libbyte.c -shared" Wait
End
Potete vedere la differenza dei risultati.
(Non capisco
perché, ricavando il valore dalla funzione Byte@(), poi non fa la sottrazione. ...ma questo forse dovrei domandarlo nella Mailing List di gambas.)
Per emulare il "
signed char" del C, ho dovuto escogitare questa modalità:
1)
Print "\nDa Gambas: "; CShort(Byte@(p)) - 256
o peggio:
2)
Print "\nDa Gambas: "; Val("&" & Hex(Byte@(p))) - 256
La domanda è:
avete una soluzione migliore rispetto a quella del punto 1) ?