2017-01-18 1 views
1

J'essaie de sauvegarder des structures de données C++ dans un ensemble de données composé HDF5. Ces structures de données contiennent des types POD et std :: string. Pour gérer correctement std :: string, pour chaque structure A, je crée une structure CA où je remplace chaque std::string par un pointeur const char* qui pointera vers la mémoire maintenue par le std::string (retour par les méthodes c_str).HDF5 C++: écrire une chaîne dans un ensemble de données composé

Cela conduit à des résultats étranges détaillés ci-dessous. J'utilise la version HDF5 1.8.13 sur un debian Jessie.

J'ai essayé de simplifier mon test au strict minimum. Voici le code pour writting un H5::DataSet (r est le groupe racine d'un fichier HDF5):

//! a simple example of C-struct with a string 
struct CString 
{ 
    //! pointer to a C-string 
    const char* value; 
}; // end of struct CString 
// compound description 
H5::CompType c(sizeof(CString)); 
c.insertMember("value", HOFFSET(CString,value),H5::PredType::C_S1); 
// value to be stored 
std::string test = "my test value"; 
// place holder 
CString ctest; 
// not working: ctest.value= test.c_str() 
ctest.value = strdup(test.c_str()); 
// data set creation 
hsize_t dim[] = {1}; 
const auto d = r.createDataSet("test",c,DataSpace(1,dim)); 
d.write(&ctest,c); 

Le point est que je dois faire une copie de la chaîne pour obtenir la valeur dans le fichier HDF5. Sinon, je reçois des ordures.

Voici le code pour lire la valeur du fichier créé:

const auto f = File("test.hf5",H5F_ACC_RDONLY); 
const auto r = f.getRoot(); 
// compound description 
H5::CompType c(sizeof(CString)); 
c.insertMember("value", HOFFSET(CString,value),H5::PredType::C_S1); 
// value to be read 
CString test; 
// reading 
const auto d = r.openDataSet("test"); 
d.read(&test,c); 
std::cout << test.value << std::endl; 

(ici File est simple wrapper autour de la classe H5File qui fournit la méthode getRoot)

Avec la copie d'un de la chaîne , la sortie est "ma valeur de test". Sans la copie a la chaîne, la sortie est "A".

Ce comportement semble incompatible avec les divers articles que j'ai lus sur l'écriture/la lecture d'une chaîne std :: string dans HDF5. Toutefois, ces publications n'ont jamais traité un jeu de données composé.

Toute aide serait grandement appréciée.

Répondre

1

J'ai finalement trouvé l'anwswer. Je dois changer la définition du membre value comme suit:

H5::CompType c(sizeof(CString)); 
H5::StrType stype(H5::PredType::C_S1, H5T_VARIABLE); 
c.insertMember("value", HOFFSET(CString,value),stype); 

Le fait que l'exemple a travaillé lors de la copie de la chaîne est une sorte de bonne fortune et a à voir avec la mise en page de la mémoire de mon test.

Cordialement