读取复合数据类型的HDF5数据集,该数据集包含多个浮点数和整数可变的集合 我试图用C++中的H5CPP库读取一个具有复合数据类型的HDF5数据集。HDF5文件是由模拟器创建的,所以不幸的是,我无法控制结构。每个单元格包含多组可变长度浮点和一组可变长度整数。h5dump显示的收割台结构为: DATASET "SET_NAME" { DATATYPE H5T_COMPOUND { H5T_VLEN { H5T_IEEE_F64LE} "dProp1"; H5T_VLEN { H5T_IEEE_F64LE} "dProp2"; H5T_VLEN { H5T_STD_I32LE} "iProp1"; H5T_VLEN { H5T_IEEE_F64LE} "dProp3"; } DATASPACE SIMPLE { ( 5, 122 ) / ( H5S_UNLIMITED, H5S_UNLIMITED ) } }

读取复合数据类型的HDF5数据集,该数据集包含多个浮点数和整数可变的集合 我试图用C++中的H5CPP库读取一个具有复合数据类型的HDF5数据集。HDF5文件是由模拟器创建的,所以不幸的是,我无法控制结构。每个单元格包含多组可变长度浮点和一组可变长度整数。h5dump显示的收割台结构为: DATASET "SET_NAME" { DATATYPE H5T_COMPOUND { H5T_VLEN { H5T_IEEE_F64LE} "dProp1"; H5T_VLEN { H5T_IEEE_F64LE} "dProp2"; H5T_VLEN { H5T_STD_I32LE} "iProp1"; H5T_VLEN { H5T_IEEE_F64LE} "dProp3"; } DATASPACE SIMPLE { ( 5, 122 ) / ( H5S_UNLIMITED, H5S_UNLIMITED ) } },c++,hdf5,C++,Hdf5,我曾尝试创建一个包含VarLenTypes的CompType,但在运行异常时会抛出异常,指出一个成员与另一个成员重叠(这是我在任何地方给定的唯一大小是包含指针的结构的大小时所期望的)。这是我到目前为止的一个摘录: #include <H5Cpp.h> typedef struct mytype_t { double* dprop1; double* dprop2; int* iprop1; double* dprop3; } mytype_t; H5

我曾尝试创建一个包含
VarLenType
s的
CompType
,但在运行异常时会抛出异常,指出一个成员与另一个成员重叠(这是我在任何地方给定的唯一大小是包含指针的结构的大小时所期望的)。这是我到目前为止的一个摘录:

#include <H5Cpp.h>
typedef struct mytype_t {
    double* dprop1;
    double* dprop2;
    int* iprop1;
    double* dprop3;
} mytype_t;

H5::CompType ctype(sizeof(mytype_t));
auto double_type = H5::PredType::NATIVE_DOUBLE;
auto int_type = H5::PredType::NATIVE_INT;
auto vdouble_type = H5::VarLenType(&double_type);
auto vint_type = H5::VarLenType(&int_type);
ctype.insertMember("dProp1", HOFFSET(mytype_t, dprop1), vdouble_type);
ctype.insertMember("dProp2", HOFFSET(mytype_t, dprop2), vdouble_type);
ctype.insertMember("vProp1", HOFFSET(mytype_t, iprop1), vint_type);
ctype.insertMember("dProp3", HOFFSET(mytype_t, dprop3), vdouble_type);

std::vector<mytype_t> data_vector;
data_vector.resize(dims[0]*dims[1]);
dataset.read(data_vector.data(), ctype);
#包括
类型定义结构mytype\t{
双*dprop1;
双*dprop2;
int*iprop1;
双*dprop3;
}mytype_t;
H5::CompType ctype(sizeof(mytype_t));
auto double\u type=H5::PredType::NATIVE\u double;
auto int_type=H5::PredType::NATIVE_int;
自动vdouble_类型=H5::VarLenType(&double_类型);
自动VIN类型=H5::VarLenType(&int类型);
插入成员(“dProp1”,HOFFSET(mytype_t,dProp1),vdouble_类型);
插入成员(“dProp2”,HOFFSET(mytype_t,dProp2),vdouble_类型);
ctype.insertMember(“vProp1”,HOFFSET(mytype_t,iprop1),vint_型);
插入成员(“dProp3”,HOFFSET(mytype_t,dProp3),vdouble_类型);
std::矢量数据\矢量;
数据向量调整大小(dims[0]*dims[1]);
读取(data_vector.data(),ctype);

如何读取这样的数据集?

HDF5文档和示例在这个问题上非常薄弱

HDF5要求用户保留可变长度数据的句柄(类型为hvl\t),并在将数组作为复合类型的成员插入时引用该句柄

这会增加保留这些句柄和向量、数组的开销。。。等。与手柄同步。也就是说,如果要保留动态数组,无论何时更改元素数,都需要更新“len”字段,无论何时重新分配数组,都需要将“p”字段设置为新数组的第一个元素

这也适用于std::vectors,请记住,无论何时在向量中添加/删除元素,都需要不断更新plen。dguest提供了一段很好的代码来实现这一点

您的案例解决方案(简化):

#包括
类型定义结构mytype\t{
双*dProp;
hvl_t dPropHandle;
int*iProp;
hvl_t iPropHandle;
}mytype_t;
H5::CompType ctype(sizeof(mytype_t));
auto double\u type=H5::PredType::NATIVE\u double;
auto int_type=H5::PredType::NATIVE_int;
自动vdouble_类型=H5::VarLenType(&double_类型);
自动VIN类型=H5::VarLenType(&int类型);
//使用句柄而不是数组指针
ctype.insertMember(“dProp”,HOFFSET(mytype_t,dPropHandle),vdouble_类型);
ctype.insertMember(“iProp”,HOFFSET(mytype_t,iPropHandle),vint_型);
std::矢量数据\矢量;
数据向量调整大小(dims[0]*dims[1]);
读取(data_vector.data(),ctype);
//相应地更新数组指针
用于(mytype\u t&m:数据\u矢量)
{
m、 dProp=dPropHandle.p;
m、 iProp=iPropHandle.p;
}
使用向量:

#include <H5Cpp.h>
typedef struct mytype_t {
    std::vector<double> dProp;
    hvl_t dPropHandle;
    std::vector<int> iProp;
    hvl_t iPropHandle;
} mytype_t;

H5::CompType ctype(sizeof(mytype_t));
auto double_type = H5::PredType::NATIVE_DOUBLE;
auto int_type = H5::PredType::NATIVE_INT;
auto vdouble_type = H5::VarLenType(&double_type);
auto vint_type = H5::VarLenType(&int_type);

// use handles instead of array pointers
ctype.insertMember("dProp", HOFFSET(mytype_t, dPropHandle), vdouble_type);
ctype.insertMember("iProp", HOFFSET(mytype_t, iPropHandle), vint_type);

std::vector<mytype_t> data_vector;
data_vector.resize(dims[0]*dims[1]);
dataset.read(data_vector.data(), ctype);

// update vectors accordingly
for(mytype_t &m : data_vector)
{
    m.dProp.assign(static_cast<double*>(m.dPropHandle.p),
    static_cast<double*>(m.dPropHandle.p) + m.dPropHandle.len);

    m.iProp.assign(static_cast<int*>(m.iPropHandle.p),
    static_cast<int*>(m.iPropHandle.p) + m.iPropHandle.len);
}
#包括
类型定义结构mytype\t{
std::向量dProp;
hvl_t dPropHandle;
std::向量iProp;
hvl_t iPropHandle;
}mytype_t;
H5::CompType ctype(sizeof(mytype_t));
auto double\u type=H5::PredType::NATIVE\u double;
auto int_type=H5::PredType::NATIVE_int;
自动vdouble_类型=H5::VarLenType(&double_类型);
自动VIN类型=H5::VarLenType(&int类型);
//使用句柄而不是数组指针
ctype.insertMember(“dProp”,HOFFSET(mytype_t,dPropHandle),vdouble_类型);
ctype.insertMember(“iProp”,HOFFSET(mytype_t,iPropHandle),vint_型);
std::矢量数据\矢量;
数据向量调整大小(dims[0]*dims[1]);
读取(data_vector.data(),ctype);
//相应地更新向量
用于(mytype\u t&m:数据\u矢量)
{
m、 dProp.分配(静态施法(m.dPropHandle.p),
静态(m.dPropHandle.p)+m.dPropHandle.len);
m、 iProp.assign(静态施法(m.IPROPCHANDLE.p),
静态(m.iPropHandle.p)+m.iPropHandle.len);
}

HDF5文档和示例在这个问题上非常薄弱

HDF5要求用户保留可变长度数据的句柄(类型为hvl\t),并在将数组作为复合类型的成员插入时引用该句柄

这会增加保留这些句柄和向量、数组的开销。。。等。与手柄同步。也就是说,如果要保留动态数组,无论何时更改元素数,都需要更新“len”字段,无论何时重新分配数组,都需要将“p”字段设置为新数组的第一个元素

这也适用于std::vectors,请记住,无论何时在向量中添加/删除元素,都需要不断更新plen。dguest提供了一段很好的代码来实现这一点

您的案例解决方案(简化):

#包括
类型定义结构mytype\t{
双*dProp;
hvl_t dPropHandle;
int*iProp;
hvl_t iPropHandle;
}mytype_t;
H5::CompType ctype(sizeof(mytype_t));
auto double\u type=H5::PredType::NATIVE\u double;
auto int_Utype=H5::PredType::NATIVE_Uint;
自动vdouble_类型=H5::VarLenType(&double_类型);
自动VIN类型=H5::VarLenType(&int类型);
//使用句柄而不是数组指针
ctype.insertMember(“dProp”,HOFFSET(mytype_t,dPropHandle),vdouble_类型);
ctype.insertMember(“iProp”,HOFFSET(mytype_t,iPropHandle),vint_型);
std::矢量数据\矢量;
数据向量调整大小(dims[0]*dims[1]);
读取(data_vector.data(),ctype);
//相应地更新数组指针
用于(mytype\u t&m:数据\u矢量)
{
m、 dProp=dPropHandle.p;
M
#include <H5Cpp.h>
typedef struct mytype_t {
    std::vector<double> dProp;
    hvl_t dPropHandle;
    std::vector<int> iProp;
    hvl_t iPropHandle;
} mytype_t;

H5::CompType ctype(sizeof(mytype_t));
auto double_type = H5::PredType::NATIVE_DOUBLE;
auto int_type = H5::PredType::NATIVE_INT;
auto vdouble_type = H5::VarLenType(&double_type);
auto vint_type = H5::VarLenType(&int_type);

// use handles instead of array pointers
ctype.insertMember("dProp", HOFFSET(mytype_t, dPropHandle), vdouble_type);
ctype.insertMember("iProp", HOFFSET(mytype_t, iPropHandle), vint_type);

std::vector<mytype_t> data_vector;
data_vector.resize(dims[0]*dims[1]);
dataset.read(data_vector.data(), ctype);

// update vectors accordingly
for(mytype_t &m : data_vector)
{
    m.dProp.assign(static_cast<double*>(m.dPropHandle.p),
    static_cast<double*>(m.dPropHandle.p) + m.dPropHandle.len);

    m.iProp.assign(static_cast<int*>(m.iPropHandle.p),
    static_cast<int*>(m.iPropHandle.p) + m.iPropHandle.len);
}