2017-09-12 6 views
0

J'utilise la bibliothèque HDF5 pour enregistrer en binaire.Initialiser un H5 :: CompType en tant que membre statique d'une classe

Je voudrais avoir des types de données "globaux" définis par l'utilisateur que j'initialise au début et que je puisse ensuite utiliser quand nécessaire.

Par exemple je veux définir un type composé pour un "Vecteur" (qui est juste une structure dont les composants sont deux doubles: x, y).

J'ai essayé la mise en œuvre de cette idée de la manière suivante (que je essentiellement pris de cette réponse: https://stackoverflow.com/a/27088552/4746978)

// inside Vector.h 
struct Vector 
{ 
    double x; 
    double y; 
} 


// inside Hdf5types.h 
#include "Vector.h" 
class Hdf5types 
{ 

private: 
    static H5::CompType m_vectorType; 

public: 
    static const H5::CompType& getVectorType(); 

}; 


//inside Hdf5types.cpp 
#include "Hdf5types.h" 
H5::CompType Hdf5types::m_vectorType = Hdf5types::getVectorType(); 

const H5::CompType& Hdf5types::getVectorType() 
{ 
    struct Initializer { 
      Initializer() { 
       m_vectorType = H5::CompType(sizeof(Vector)); 
       m_vectorType.insertMember("x", HOFFSET(Vector, x), H5::PredType::NATIVE_DOUBLE); 
       m_vectorType.insertMember("y", HOFFSET(Vector, y), H5::PredType::NATIVE_DOUBLE); 
      } 
    }; 
    static Initializer ListInitializationGuard; 
    return m_vectorType; 
} 

Le code compile mais je reçois un problème lors de l'exécution comme une exception est levée:

Exception levée: violation d'accès en lecture.

this-> était nullptr.

"this" fait référence à un objet appelé "IdComponent" dans la bibliothèque HDF5. Je ne sais pas comment procéder car je n'ai pas le temps de creuser dans la bibliothèque. Peut-être que quelqu'un qui connaît HDF5 a une solution!

Répondre

1

Vous attribuez la valeur trop tôt lors du démarrage du programme. Donc, votre affectation statique appelle la fonctionnalité de la bibliothèque HDF5, qui n'a pas encore été instanciée. Donc SIGSEV.

Qu'est-ce que vous pourriez faire serait:

// inside Hdf5types.h 
#include <H5Cpp.h> 
#include "Vector.h" 

class Hdf5types{ 

private: 
    static H5::CompType* m_vectorType; 

public: 
    static const H5::CompType& getVectorType(); 

    Hdf5types(); 

}; 

#include "hdf5types.h" 

H5::CompType* Hdf5types::m_vectorType = nullptr; 

Hdf5types::Hdf5types() {} 

const H5::CompType& Hdf5types::getVectorType() { 
    if (m_vectorType == nullptr) { 
    struct Initializer { 
     Initializer() { 
     m_vectorType = new H5::CompType(sizeof(Vector)); 
     m_vectorType->insertMember("x", HOFFSET(Vector, x), H5::PredType::NATIVE_DOUBLE); 
     m_vectorType->insertMember("y", HOFFSET(Vector, y), H5::PredType::NATIVE_DOUBLE); 
     } 
    }; 
    static Initializer ListInitializationGuard; 
    } 
    return *m_vectorType; 
} 

Cela paresseusement m_vectorType initialise.

+1

Merci. Cela a résolu mon problème! Je suppose que je vais devoir libérer cette mémoire allouée à droite? Je ne suis pas sûr si le faire dans le destructeur fonctionnera, parce que je ne crée aucun objet Hdf5. Qu'est-ce que tu penses? – Turms

+0

valgrind ne ferme pas que l'objet n'est pas libéré. Mais vous devez absolument ajouter un destructeur. –