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.