Newsgroup: it.comp.programmare.win32
Titolo: riguardo la persistenza delle strutture

Ciao a tutti...sono alle prese con un problema curioso...
Ho delle strutture così definite:
struct __Vertex
{
float x; float y; float z;
};
typedef struct __Vertex Vertex;
struct __Poly
{
Vertex vertices[3];
};
typedef struct __Poly Poly;
struct __Mesh
{
int num_poly;
Poly* _polygons;
};
Dopo aver popolato la struttura Mesh ho bisogno di scriverla su un
file in formato binario, per poterla recuperare successivamente, ed è
quì che casca l'asino (cioè io).
Se apro il file generato con un viewer di file binari i valori non
tornano. Leggo correttamente solo l'intero "num_poly", tutti gli altri
valori non stanno nè in cielo nè in terra.
Esempio:
12   12063936          0          0          0          0          0
0          0          0          0          0          0
0          0
0          0          0          0          0          0
0          0
0          1          0          0          0          0
12053648          0
0          0         21         31          0          0          0
12053984
....e così via...
Questo è il codice che scrive la struttura su file:
Mesh m;
// valorizzazione struttura....
int meshSize = numPoly * sizeof(Poly) + sizeof(int);
ofstream f;
f.open("mymesh.joj", std::ios::out | std::ios::binary);
f.write(reinterpret_cast<const char *>(&m), meshSize);
f.close();
Ho debuggato fino alla procedura di scrittura su file e la struttura
viene correttamente valorizzata, quindi il problema dev'essere proprio
nella scrittura del file.
Sono praticamente alla frutta...spero che qualcuno sappia darmi una
dritta!
Intanto un saluto a tutti e buon lavoro!

Jojo ha scritto:

Dove definisci Mesh? (direi che è un typedef Mesh __Mesh)...
A naso, direi che se cerchi di scrivere un puntatore sul file, ottieni 
esattamente un gran papocchio.
Se non dico scemenze, reinterpret_cast non fa altro che ritornare un 
puntatore convertito in quello che gli dici (cioè un <const char *>).
Quindi 12 è numPoly, 12063936 è probabilmente l'indirizzo di _polygons 
espresso come un puntatore ad un carattere.
Ma perché non ti fai una classe con un metodo write ed un metodo toString?
Andrea


Perchè a mio avviso il problema non cambia. Avrei comunque una
struttura dati da scrivere e non so come farlo.
Ho pensato anch'io che molto probabilmente veniva scritto l'indirizzo
di _polygons, ma non sono riuscito ad ovviare al problema.
Tu come faresti?
Grazie, Matteo

 
Bisogna vedere come fai a popolare _polygons: nella struttura hai solo 
un puntatore, immagino che adoperi un vettore (perché nella struttura 
non ci sono tracce di puntatori ad altri _polygons).
for (int i = 0; i < num_poly; i++){
	f.write(_polygons[i], sizeof(*_polygons));
}
magari funziona pure.
Comunque, secondo me, usando strutture e puntatori in quel modo stai 
scherzando con il fuoco.
Inoltre questo tipo di file non è portabile tra piattaforme diverse (ma 
immagino che non sia un problema).
Andrea


L'obiettivo sarebbe poter far girare il codice sia su piattaforma
windows che su linux.
A quanto ne so io utilizzando codice C puro, come in questo caso, la
portabilità dovrebbe essere garantita, ma magari mi sbaglio....
Ad ogni modo, se ritenete che il mio approccio sia sbagliato,
qualunque alternativa che si ritenga valida è bene accetta.
Grazie


Allora tenta così:
f.write(m.num_poly, sizeof(int)); // salvi il numero di poligoni
f.write(*((char *)m._polygons), sizeof(_polygons)*m.num_poly);	// scrivi 
l'area indirizzata da m._polygons
La lettura la fai con:
Mesh m;
f.read((char *)&m.num_poly, sizeof(int));
m._polygons = (Poly *)malloc(m.num_poly*sizeof(Poly));
f.read((char *)m._polygons, m.num_poly*sizeof(Poly));
Al solito, forse funziona: non uso quasi mai metodi di questo genere, ho 
un po' di ruggine.
Il discorso sulla portabilità lo facevo in base ai dati, non allo stile 
di scrittura C, ed a queste considerazioni:
1) tu non sai dove sono allocati i dati;
2) computer diversi hanno allocazioni diverse;
3) momenti diversi sullo stesso computer possono ritornare 
indirizzamenti diversi.
Quindi quando fai la read, non puoi leggere direttamente una struttura 
Mesh, perché il *_polygon è un puntatore ad un'area che può cambiare in 
modo arbitrario, ed in più tu nella write salvi *il puntatore*, non 
*l'area indirizzata dal puntatore*.
Inoltre non è detto che cambiando processore, anche all'interno della 
stessa famiglia, i dati float restino validi, se scritti in quel modo. 
Ma questa è un'ipotesi puramente accademica, i float (se conformi allo 
standard IEEE) sono rappresentati tutti allo stesso modo.
Probabilmente non sarai in grado di scambiare il file di dati tra una 
versione compilata per Intel ed una compilata per SPARC o PPC.
Andrea