Anthus napisał(a)
Zrobiłem serializację za pomocą boost:
klasy.hpp:(...)
mainwindow.cpp:(...)
mainwindow.h:(...)
Tworzy się plik materials.dat przy pierwszym uruchomieniu, jednak podczas wykonywania polecenia:
iar >> SubsList;
program nieoczekiwanie przerywa pracę.
Rozwiazales problem, ale jeszcze sie odezwe:)
Zdziwilo mnie to bardzo, poniewaz nigdy dotad z boost::serialization nie mialem zadnych wiekszych problemow, a Twoj kod generalnie wygladal prawidlowo poza jednym drobiazgiem.
Poskladalem u siebie analogiczny, uzupelniajac o rzeczy które wyciałes:
#include <vector>
#include <boost/serialization/serialization.hpp>
class Substance
{
friend class boost::serialization::access;
public:
~Substance() {}
Substance(){ }
Substance (const Substance & rhs) {itsName = rhs.itsName;itsDensity=rhs.itsDensity;memcpy(itsElasticity,rhs.itsElasticity,sizeof(itsElasticity));}
std::string getName() const {return itsName; }
//QString getQName() const { QString qname( itsName.c_str() ); return qname; }
void setName(std::string N) { itsName = N; }
void getElasticity(float (&Elasticity)[6][6]) const;
void setElasticity(float (&Elasticity)[6][6]){memcpy(itsElasticity,Elasticity,sizeof(itsElasticity));}
float getDensity() const { return itsDensity; }
void setDensity(float D) { itsDensity = D; }
public:
std::string itsName;
float itsElasticity[6][6];
float itsDensity;
};
#include <vector>
#include <boost/serialization/serialization.hpp>
#include "klasy.hpp"
typedef std::vector<Substance> SubstanceList;
namespace boost { namespace serialization {
template<class Archive>
void serialize(Archive & ar, Substance& v, const unsigned int version)
{
ar & v.itsName;
ar & v.itsDensity;
ar & v.itsElasticity; //// (A)
}
} }
#include <fstream>
#include <vector>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include "main.h"
int main()
{
using namespace std;
ifstream plik("materials.dat",ios::binary); //F
if (!plik)
{
SubstanceList SubsList;
Substance Subs;
Subs.setName("Ojej");
Subs.setDensity(1000);
float tmp[6][6] = { {1,2,3,4,5,6}, {11,12,13,14,15,16}, {21,22,23,24,25,26}, {31,32,33,34,35,36}, {41,42,43,44,45,46}, {51,52,53,54,55,56}, };
Subs.setElasticity(tmp);
SubsList.push_back(Subs);
ofstream fout("materials.dat", ios::binary);
boost::archive::binary_oarchive oar(fout);
oar << SubsList;
fout.close(); //// (B)
} else
{
SubstanceList SubsList;
boost::archive::binary_iarchive iar(plik); //// (E)
iar >> SubsList; //// (D)
plik.close(); //// (C)
}
}
po pierwsze, popełniłeś u siebie
ar & v.itsElasticity[6][6]; //// (A)
powoduje to zapisanie dosc kuriozalnego pojedynczego "elementu" tablicy, Ty zas chciales zapisac tablice:
ar & v.itsElasticity; //// (A)
po drugie, linijki (B) oraz (C) w zasadzie nie powinny sie tam byly znalezc, acz nie szkodza one zwykle nikomu. w C++ destruktory strumieni powoduja ich zamkniecie, wiec wystarczy ze "fout" oraz "plik" wyjda poza 'scope' i zamkna sie same. Co wiecej, tyczy sie to rowniez OAR i IAR - siłą rzeczy sa tworzone PO strumieniach, wiec ich destruktory odpala sie najpierw, a dopiero potem destr. strumieni. W momencie gdy Ty najpierw recznie odpalasz close na strumieniu, teoretycznie odcinasz OAR'owi mozliwosc zapisania sobie czegos na koncu pliku po juz zakonczonej serializacji. On tego nie robi, przynajmniej w tej wersji, ale generalnie, jesli juz uzywamy RAII, to uzywajmy jej zamiast odcinac komus gałąź na ktorej siedzi:)
szczerze mowiac, nie wiem skad wzial Ci sie blad wtedy, powyzszy kod dziala u mnie poprawnie. Byc moze wpadka w miejscu (A) powodowala u Ciebie pechowe uszkodzenie pamieci - ostatecznie serializer posłusznie wpisywał w element '6-6' jakąś tam wartosc z pliku.
inna rzecz, ze jezeli Twoj oryginalny program wygladal lekko inaczej, to tez sie mogl sypac, jednak nie w miejscu 'D', tylko w 'E'. Np. jezeli po zapisaniu OAR'a jakos wskakiwales do bloku czytajacego plik, np. ot tak dla sprawdzenia, to z linijki E moglbys otrzymywac wyjatek 'invalid signature' lub cos podobnego, bioracy sie stad, ze ifstream z linii F caly czas sadzi ze plik nie istnieje/ał i trzeba tego ifstreama szturchnac..
sadze, ze jednak miales pecha z powodu linii (A).
nie rezygnuj z boost::serialization, przyda Ci sie bardzo jak bedziesz mial bardziej skomplikowane grafy do zrzucenia do pliku:)