I am successfully using HDF5 in our project (DREAM3D.bluequartz.net) but I am getting spurious errors when reading from some of our HDF5 files.
This is the error from the HDF5 library:
HDF5-DIAG: Error detected in HDF5 (1.8.10-patch1) thread 0:
#000: /Users/mjackson/Workspace/hdf5-1.8.10-patch1/src/H5F.c line 443 in H5Fget_obj_count(): not a file id
major: Invalid arguments to routine
minor: Bad value
HDF5-DIAG: Error detected in HDF5 (1.8.10-patch1) thread 0:
#000: /Users/mjackson/Workspace/hdf5-1.8.10-patch1/src/H5F.c line 2044 in H5Fclose(): invalid file identifier
major: Invalid arguments to routine
minor: Inappropriate type
The value of the file id is 16777216 which seems sort of odd as it is always this value no matter how many times I run the program (just an observation). I have a "sentinel" c++ class that keeps an pointer to the file id so when I goes out of scope the HDF5 file will get closed:
class HDF5ScopedFileSentinel
{
public:
HDF5ScopedFileSentinel(hid_t* fileId, bool turnOffErrors);
virtual ~HDF5ScopedFileSentinel();
void setFileId(hid_t* fileId);
hid_t* getFileId();
private:
hid_t* m_FileId;
bool m_TurnOffErrors;
herr_t (*_oldHDF_error_func)(hid_t, void *);
void* _oldHDF_error_client_data;
};
The destructor looks like this:
HDF5ScopedFileSentinel::~HDF5ScopedFileSentinel()
{
if (m_TurnOffErrors == true)
{
H5Eset_auto(H5E_DEFAULT, _oldHDF_error_func, _oldHDF_error_client_data);
}
if (*m_FileId > 0) {
H5Utilities::closeFile(*m_FileId);
*m_FileId = -1;
}
}
The call to H5Utilities::closeFile is this:
herr_t H5Utilities::closeFile(hid_t &fileId)
{
herr_t err = 1;
if (fileId < 0) { // fileId isn't open
return 1;
}
// Get the number of open identifiers of all types
// except files
ssize_t num_open = H5Fget_obj_count(fileId, H5F_OBJ_DATASET | H5F_OBJ_GROUP |
H5F_OBJ_DATATYPE | H5F_OBJ_ATTR);
if (num_open > 0) {
std::cout << "WARNING: Some IDs weren't closed. Closing them." << std::endl;
std::vector<hid_t> attr_ids(num_open, 0);
H5Fget_obj_ids(fileId, H5F_OBJ_DATASET | H5F_OBJ_GROUP |
H5F_OBJ_DATATYPE | H5F_OBJ_ATTR,
num_open, &(attr_ids.front()) );
for (int i=0; i<num_open; i++)
{
char name[1024];
::memset(name, 0, 1024);
//hid_t obj_type = H5Iget_type(attr_ids[i]);
ssize_t charsRead = H5Iget_name( attr_ids[i], name, 1024);
if (charsRead < 0)
{
std::cout << "Error Trying to get the name of an hdf object that was not closed. This is probably pretty bad. " << __FILE__ << "(" << __LINE__ << ")" << std::endl;
return -1;
}
std::cout << "H5 Object left open. Id=" << attr_ids[i] << " Name='" << name << "'" << std::endl;
H5Utilities::closeHDF5Object(attr_ids[i]);
}
}
err = H5Fclose(fileId);
if (err < 0) {
/* !!!! I DROP IN HERE !!!!!! */
std::cout << "Error Closing HDF5 File. " << err << std::endl;
}
fileId= -1;
return err;
}
The code that is the problem is something like this:
{
hid_t fileId = -1;
fileId = H5Utilities::openFile(m_InputFile->text().toStdString(), true);
if (fileId < 0) {
return;
}
// This should automatically close the file when we leave this function
HDF5ScopedFileSentinel sentinel(&fileId, true);
// READ A BUNCH OF DATA FROM THE HDF5 File Without any issue
}
When the sentinel object goes out of scope I get the HDF5 error. If I remove the sentinel object completely and directly call H5Utilities::closeFile(..) then I do NOT get this error. Ideas?
I am crossing Library boundaries with these calls if that matters?
This is all on OS X 10.6.8 with the Stock Xcode compilers (Xcode 3.2.6) and a self built HDF5 1.8.10-patch_1.
Any ideas on what might the problem be would be great. I can try to pair it down to an more compact example if needed.
···
___________________________________________________________
Mike Jackson Principal Software Engineer
BlueQuartz Software Dayton, Ohio
mike.jackson@bluequartz.net www.bluequartz.net