hdf — C ++ HDF5 извлекает один элемент составного типа данных

Я пишу библиотеку c ++, которая читает файлы hdf5, созданные другой библиотекой.

Эти файлы hdf5 содержат много составных наборов данных с различными составными типами данных. Я хочу перевести каждый составной тип данных в структуру C ++.

Для строк (переменной длины или массива символов фиксированного размера) я хочу использовать std :: string в структуре C ++.

В настоящее время я использую промежуточную структуру C (используя char* или же char[] переменные), которые я затем преобразовать в окончательную структуру C ++. Однако это приводит к большому количеству шаблонного кода.

Если бы я мог извлечь элементы данных по элементам, я мог бы сделать что-то вроде:

std::string name = extract<std::string>(d,"name");

где d — составной набор данных.

Является ли это возможным

0

Решение

Я нашел рабочее решение. Я размещаю это здесь, возможно кто-то найдет это полезным. Идея заключается в создании объекта CompoundExtractor, который содержит буфер, в котором читается все соединение. Затем можно извлечь членов по одному, используя метод извлечения шаблона. На этом этапе соответствующая специализация (здесь не сообщается) позволяет надлежащим образом обрабатывать строки.
С Уважением,

struct MADNEX_VISIBILITY_EXPORT CompoundExtractor
{
/*!
* \brief constructor
* \param[in] d: data set
*/
CompoundExtractor(const DataSet&);
//! destructor
~CompoundExtractor();
/*!
* \return a member of the compound of the given type
* \param[in] n: member name
*/
template<typename T>
T extract(const std::string&) const;
/*!
* \return a member of the compound of the given type
* \param[in] n: member name
*/
template<typename T>
T extract(const char *) const;
private:
//! the description of the compound data type
H5::CompType ctype;
//! an intermediate storage for the compound data type
std::vector<char> data;
}; // end of CompoundExtractor

template<typename T>
T CompoundExtractor::extract(const char *n) const{
const auto i = this->ctype.getMemberIndex(n);
const auto o = this->ctype.getMemberOffset(i);
return *(reinterpret_cast<const T *>(this->data.data()+o));
} // end of CompoundExtractor::extract

template<typename T>
T CompoundExtractor::extract(const std::string& n) const{
const auto i = this->ctype.getMemberIndex(n);
const auto o = this->ctype.getMemberOffset(i);
return *(reinterpret_cast<const T *>(this->data.data()+o));
} // end of CompoundExtractor::extract

CompoundExtractor::CompoundExtractor(const DataSet& d)
{
const auto dtype = d.getDataType();
if(dtype.getClass()!=H5T_COMPOUND){
throw(std::runtime_error("CompoundExtractor: invalid data set"));
}
this->ctype = H5::CompType(d);
this->data.resize(ctype.getSize());
d.read(this->data.data(),ctype);
}

CompoundExtractor::~CompoundExtractor() = default;
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]