Newsgroup: it.comp.java
Titolo: da C++ a Java...

Ciao a tutti. Ecco il mio problema:
devo eseguire il porting di un'applicazione da C++ a Java. Niente di
impressionante se non per il fatto che la mi applicazione deve leggere dei
dati da socket...e qui esce fuori il problema.
Nell'applicazione in C++ si eseguono 2 read() sulla socket: una per
determinare quanti dati verranno trasmessi e la seconda per leggere
effettivamnete i dati. Nella prima read() si leggono una qunatità di dati
pari a sizeof(struct header) che è così strutturata:
struct header
{
        unsigned long number;
        struct timeval time;
        unsigned long option;
        unsigned long byte;
};
La seconda read() è analoga alla prima e si leggono blocchi di dati pari a
sizeof(ObjProperty) la cui struttura è:
struct ObjProperty
{
        int     id;
        float   position[3];
        float   rotation[3];
        int     state;
};
Ora il mio problema è di riuscire a leggere in Java esattamente la stessa
quantità di byte che leggo in C++ per poter fare i dovuti calcoli. Quello
che mi lascia perplesso è la dimensione di "struct timeval" poichè per il
resto non credo che ci siano particolari difficoltà dovute alla lunghezza
dei campi.
Avete già fatto qualcosa del genere? Sapere darmi quaòche dritta o anche
solo dei link di riferimanto?
Grazie  a tutti in anticipo
Japs

 dei campi.
In realtà ci sarebbero diverse cose che mi farebbero riflettere. Per
esempio, tutti quei interi devi accertarti che siano inviati con il
network order (o big endian che dir si voglia) che è inverso da come
li manderebbe un programma windows.
A parte questo problema che sicuramente avrai trattato, io leggerei la
struttura in un buffer di byte e poi la elaborerei trasformandola nel
tipo opportuno.

 writes:
J> Ora il mio problema è di riuscire a leggere in Java esattamente la
J> stessa quantità di byte che leggo in C++ per poter fare i dovuti
J> calcoli. Quello che mi lascia perplesso è la dimensione di "struct
J> timeval"
Attenzione all'allineamento dei componenti nelle strutture.
Il talk di  Berkeley (BSD) aveva delle istruzioni  simili, e quando si
fece il  port verso macchine  M68020 col compilatore Green  Hills (dal
VAX) ci  furono problemi per  il fatto che  la struttura che  si usava
occupava 22  byte sotto BSD su VAX  e 24 sotto Olivetti  X/OS su 68020
(LSX3020).
Può sembrare  archeologia, ma  non lo è,  guardare solo le  opzioni di
allineamento  del codice  che  si hanno  sulle  CPU Intel  con vari  e
diffusi compilatori.
-- 
 /\            ___
/___/\__|_|\_|__|___Gian Uberto Lauri_____________________
  //--\ | | \|  |   Integralista GNUslamico  
\/		    e allevatore di bug da competizione

 tipo opportuno.
A questo avevo penato, però la struct timeval quanti byte ha? E' solo quello
il problema.. per il resto dovrebbe essere più facile.

 A questo avevo penato, però la struct timeval quanti byte ha?
Penso sizeof(timeval), no?

> A questo avevo penato, perň la struct timeval quanti byte ha?
VV> Penso sizeof(timeval), no?
Che perň se non ricordo male varia con l'allineamento scelto in
fase di creazione del programma.
Quindi occorre essere certi che  il programma in C++ rimanga compilato
con quell'allineamento.


 con quell'allineamento.
Oppure evitare di trasmettere strutture e bit field a occhi chiusi.
Ciao
Mirko

Penso sizeof(timeval), no?
Mi pare che sizeof ritorni il numero di sizeof(char) e non di byte.
Cioe' char e' l'unita' di misura, ovvero sizeof(char) ritorna sempre 1 anche 
se un char e' fatto di n byte. 

> compilato con quell'allineamento.
MV> Oppure evitare di trasmettere strutture e bit field a occhi
MV> chiusi.
Concordo!


> Penso sizeof(timeval), no?
c> Mi pare che sizeof ritorni il numero di sizeof(char) e non di byte.
c> Cioe' char e' l'unita' di misura, ovvero sizeof(char) ritorna
c> sempre 1 anche se un char e' fatto di n byte.
Che ricordi  io in  C i char  _sono_ di  un byte che  nella stragrande
maggioranza dei casi  sono 8 bit -  non penso che tu abbia  a che fare
con un mainframe IBM o un CDC6600. I char unicode sono definiti con un
altro tipo.


>> Penso sizeof(timeval), no?
c> Mi pare che sizeof ritorni il numero di sizeof(char) e non di byte.
GUL> Che ricordi io in C i char _sono_ di un byte
Non ho tra le mani il  K&R, ma la documentazione online che ho trovato
conferma che ricordo bene.


 con quell'allineamento.
Bisogna sicuramente evitare di mandare immagini di memoria da un
programma all'altro e peggio ancora da una macchina all'altra.

 se un char e' fatto di n byte.
Al di la del fatto che in C sizeof(char) è garantito per standard che
restituisca 1, non è vero quello che dici. sizeof(tipo) restituisce la
dimensione in byte.

Ragazzi grazie a tutti! :) Ora ho le idee un po' più chiare e proverò a
buttare giù qualche linea di codice per vedere se funzia. Tanto poi se non
riesco vi scasso sul NG! :-P
Grazie ancora a tutti,
Japs

 Penso sizeof(timeval), no?
Allora, penso di aver risolto...penso! Premetto che il programma originale
in C++ gira sotto linux. Ho effettuho scritto queste 2 righe di codice in C
per determinare la grandezza delle struct e dei singoli campi.
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
struct header
{
        unsigned long number;
        struct timeval time;
        unsigned long option;
        unsigned long byte;
};
struct ObjProperty
{
        int     id;
        float   position[3];
        float   rotation[3];
        int     state;
};
int main(int argc,char** argv)
{
        printf("\n\n\tDimensione struct header: %d\n", sizeof(struct header));
        printf("\t|-- unsigned long number: %d\n", sizeof(unsigned long));
        printf("\t|-- struct timeval time: %d\n", sizeof(struct timeval));
        printf("\t|-- unsigned long option: %d\n", sizeof(unsigned long));
        printf("\t|-- unsigned long byte: %d\n", sizeof(unsigned long));
 
        printf("\n\n\tDimensione struct ObjProperty: %d\n", sizeof(struct
ObjProperty));
        printf("\t|-- int id: %d\n", sizeof(int));
        printf("\t|-- float position[3]: %d\n", sizeof(float[3]));
        printf("\t|-- float rotation[3]: %d\n", sizeof(float[3]));
        printf("\t|-- int state: %d\n\n", sizeof(int));
}
A questo punto dovrei sapere la quantità di byte necessari per leggere dalla
socket. Che ne dite? Può essere una soluzione, un inizio?
Ciao, Japs

 writes:
[... codice C omesso ...]
J> A questo punto dovrei sapere la quantità di byte necessari per
J> leggere dalla socket. Che ne dite? Può essere una soluzione, un
J> inizio?
E' un caso abbastanza fortunato, timeval ha una dimensione di 8 quindi
su  macchine  a  32  bit  la struttura  header  avrà  esattamente  una
dimensione di 4  + 8 + 4 +  4 byte e non dovrebbe  generare warning di
cattivo allineamento con  le opzioni -Wpacked e -Wpadded  di gcc sulle
macchine in questione. 
Linux PPC o Sparc ? Mi pareva di aver letto big endian :)


 
In verità è su pc normale...ci sono problemi? spero vivamente di no!
 :-(

> 
j> In verità è su pc normale...ci sono problemi? spero vivamente di no!
J>  :-(
Occhio che è little endian. Se spari fuori gli oggetti con una write()
brutale ti  trovi a dover fare un  po' di lavoro in  Java per riaverli
big endian.  Se invece  c'è di mezzo  codice che  SA di essere  su una
macchina little  endian e si preoccupa  di fare output  big endian, no
problem.



si ha ragione vincent, ma ritorna sempre vero in qualsiasi architettura 
l'istruzione
sizeof(char) == 1; 

> 
c> si ha ragione vincent, ma ritorna sempre vero in qualsiasi
c> architettura l'istruzione sizeof(char) == 1;
Il fatto che un char abbia la dimensione di un byte per definizione è
slegato dalla dimensione del byte.



e' quello che dico anche io...e aggiungo di almeno 8 bit. 

 writes:
c> e' quello che dico anche io...e aggiungo di almeno 8 bit.
Azz, credo che il CDC6600 li avesse di 6 bit...
(Nota: proprio perché il byte non č garantito di 8 bit in
telecomunicazioni si parla di ottetti)
