HDF5:复合数据类型,用于写入包含指向另一个结构的指针的结构

Posted

技术标签:

【中文标题】HDF5:复合数据类型,用于写入包含指向另一个结构的指针的结构【英文标题】:HDF5: compound data type to write a struct containing a pointer to another struct 【发布时间】:2018-03-04 08:38:44 【问题描述】:

我正在尝试向 HDF5 写入一个包含指向另一个指针的结构。像这样的:

typedef struct
    int32_t  method;
    void*    methodParams;
    float    result;
Measure;

typedef struct
    int32_t    param1;
    int32_t    param2;
OneMethod;

以下描述复合数据类型的代码不起作用:

Measure value;
hid_t method_tid;
hid_t measure_tid;

method_tid = H5Tcreate(H5T_COMPOUND, sizeof(OneMethod));
H5Tinsert(method_tid, "P1", HOFFSET(OneMethod, param1), H5T_NATIVE_INT32);
H5Tinsert(method_tid, "P2", HOFFSET(OneMethod, param2), H5T_NATIVE_INT32);

measure_tid = H5Tcreate(H5T_COMPOUND, sizeof(Measure));
H5Tinsert(measure_tid, "Method", HOFFSET(Measure, method), H5T_NATIVE_INT32);
H5Tinsert(measure_tid, "Params", HOFFSET(Measure, methodParams), method_tid);
H5Tinsert(measure_tid, "Result", HOFFSET(Measure, result), H5T_NATIVE_FLOAT);

hsize_t dim[] =  1 ;
hid_t space = H5Screate_simple(1, dim, NULL);

hid_t dataset = H5Dcreate(objid, name, measure_tid, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
herr_t ret = H5Dwrite(dataset, measure_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, &value);

H5Tclose(method_tid);
H5Tclose(measure_tid);
H5Sclose(space);
H5Dclose(dataset);

复合数据类型已写入,但缺少 methodParams 字段。我猜是因为我没有指示库在其位置上期待一个指针。我该怎么做?

编辑

请考虑结构是带有指针的,因为每个方法(由第一个结构的字段给出)具有不同的数量种类的参数。当然,一种方法是合并结构第一级所有方法中的所有参数,这是我想避免的。

【问题讨论】:

【参考方案1】:

H5Tinsert() 调用只是为存储布置字节,该结构中的实际内容是一个指针,而不是指向的东西。除了填充之外,您发送给库的内存由一个 int、一个指针和一个浮点数组成。该库将简单地尝试根据您在 H5Tinsert() 调用中告诉它的有关类型排列的内容来对该内存进行切片和切块。它不会解析复杂数据结构中的指针(人们在尝试发送使用指向 HDF5 的指针构建的多维数组时经常会对此感到困惑)。

最直接的做法是将结构修改为如下所示:

typedef struct
    int32_t  method;
    int32_t  param1;
    int32_t  param2;
    float    result;
hdf5_Measure;

并手动填充,至少对于 HDF5 I/O。

【讨论】:

谢谢,我明白这一点,但这是我已经考虑过的,我想避免。请查看我的编辑。还有其他想法吗? 没有直接的方法可以做你想做的事。 HDF5 库 I/O 调用以最小的转换消耗和发出数据缓冲区。基本上只是类型转换和(压缩)过滤器。它们不会为您追逐指针或展平复杂的数据结构。打包和解包数据由客户端决定。 请记住,HDF5 旨在擅长存储相同类型的数据数组,例如您在成像、物理模拟等中发现的数据。它可能无法很好地存储数据你的异质性水平。 HDF5 数据集确实不是为这类事情设计的。 如果您在该代码中执行的操作是对其他一些 HDF5 数据的辅助,您可能会研究将该结构数据存储为 HDF5 属性(查看 H5A API 调用),您可以将其附加到数据集( s)、group(s) 等。您也可以考虑为结构数据使用其他一些存储方案。例如,您可以将这些数据作为 JSON 发出。如果您需要使用 HDF5 文件保持正交存储,您可以查看 h5jam/h5unjam 工具。这些允许您将文件添加到 HDF5 文件以创建混合文件。

以上是关于HDF5:复合数据类型,用于写入包含指向另一个结构的指针的结构的主要内容,如果未能解决你的问题,请参考以下文章

HDF5Cpp 扩展复合数据集 Hyperslab 问题

通过 h5py (HDF5) 写入具有可变长度字符串的复合数据集

带有指针数组的 HDF5 结构

如何在 C++ 中将 stl::string 写入 HDF5 文件

HDF5 复合类型 Native vs. IEEE

如何在 HDF5 C# 上创建复合数据集