【问题标题】:Write dynamically sized composite type datasets with HDF5 C++使用 HDF5 C++ 编写动态大小的复合类型数据集
【发布时间】:2013-12-17 17:35:27
【问题描述】:

我正在尝试将动态分配的结构写入 HDF5 复合数据集,类似于this example。我已经从我的代码中发布了相关的 sn-ps,它编译并被其他工作的 H5 代码包围,这些代码可以毫无问题地编写其他数据结构(标量、数组、属性)。另外,我不是 C++ 专业人士,所以如果有什么不合适的地方,请告诉我。

首先,我有一个动态分配的op 数组,长度为nop 在运行时确定:

#include "H5Cpp.h"

int main ()
{
    unsigned int nop = 0;
    typedef struct op_t {
        int id;
        double x;
        double y;
        double z;
    } op_t;
    /* there's a for-loop that determines value of nop, e.g. 1 */
    nop = 1;
    op_t *op = new op_t[nop];
    // populate with example data
    for (int n = 0; n < nop; n++)
    {
        op[n].id = n + 1;
        op[n].x = 10.0 * n + 10.0;
        op[n].y = 200.0 * n + 20.0;
        op[n].z = 30.0 * n + 30.0;
    }

我担心的一个问题是op 不连续,但我不确定。现在是 HDF5 部分:

    // Move data to HDF5 composite data structure
    H5::H5File h5file ("myfile.h5", H5F_ACC_TRUNC);
    H5::Group root = h5file.openGroup("/");

    hsize_t op_dim[] = {nop};
    H5::DataSpace op_dataspace(1, op_dim);

    H5::CompType op_type(sizeof(op_t));
    op_type.insertMember("id", HOFFSET(op_t, id), H5::PredType::NATIVE_INT);
    op_type.insertMember("x", HOFFSET(op_t, x), H5::PredType::NATIVE_DOUBLE);
    op_type.insertMember("y", HOFFSET(op_t, y), H5::PredType::NATIVE_DOUBLE);
    op_type.insertMember("z", HOFFSET(op_t, z), H5::PredType::NATIVE_DOUBLE);

    H5::DataSet op_ds = root.createDataSet("obs_point", op_type, op_dataspace);
    op_ds.write(op, op_type);
    op_ds.close();
    delete [] op;

    h5file.flush(H5F_SCOPE_GLOBAL);
    h5file.close();
    return 0;
}

我的结果表不是我所期望的,因为 (1):数据值错误,(2) 标题名称不正确。例如,nop == 1,我看到:

È 是如何进入标题名称的?标题名称似乎每隔一段时间就会更改为其他垃圾字符,并对代码进行细微更改。此外,数据结构并未复制或写入 HDF5 数据集。

我正在使用 Microsoft Visual C++ 2010 Express 和一个预编译的 HDF5 1.8.11 共享库,除了创建/编写 H5::CompType 之外,该库在这个项目中表现出色。


更新 1 这个简短的示例在 Debian 上使用 h5c++ 令人讨厌,因此它可能与 MS Visual C++ 有关。

更新 2 该问题仅发生在 Debug 构建目标上,并且仅针对 H5::CompType。 Release 构建目标的问题“消失”了,我觉得这很奇怪而且很烦人。

【问题讨论】:

    标签: c++ visual-c++ struct dynamic-arrays hdf5


    【解决方案1】:

    我今天一直在努力解决这个确切的问题。查看 CompData.insertMember 的代码没有帮助。它实际上只是 H5Tinsert 的一个薄包装,但是我怀疑关于 H5std_string 存在一些可疑行为(它的类型定义为 std::string)。

    以下不起作用,并返回我的成员名称之一不唯一的错误:

    typedef struct {
      uint32_t data1;
      uint32_t test;
    } simple_s;
    CompType mydata(sizeof(simple_s));
    mydata.insertMember(name1, HOFFSET(simple_s, data1), PredType::NATIVE_UINT32);
    mydata.insertMember(name2, HOFFSET(simple_s, test), PredType::NATIVE_UINT32);
    

    但是,如果我改用

    H5Tinsert(mydata.getId(), "data1", HOFFSET(simple_s, data1), H5T_NATIVE_UINT32);
    H5Tinsert(mydata.getId(), "test", HOFFSET(simple_s, test), H5T_NATIVE_UINT32);
    

    而不是 insertMember 它按预期工作。或者,这也有效,

    const H5std_string name1("data1");
    const H5std_string name2("test");
    mydata.insertMember(name1, HOFFSET(simple_s, data1), PredType::NATIVE_UINT32);
    mydata.insertMember(name2, HOFFSET(simple_s, test), PredType::NATIVE_UINT32);
    

    所以似乎只有当您传递原始 cstrings 以进行转换时。真令人沮丧,即使通过 static_cast("data1") 进行的 static_casting 也不起作用。我在 VS2013 32bit 上以调试模式编译,我自己使用相同的编译器编译了 HDF5。为 std::string 设置了调试标志,这是我唯一的解释,但我不明白它是如何干扰的。

    【讨论】:

    • 看这篇文章之前没注意,但是我们也是直接使用H5Tinsert(),虽然我们一般使用C++ H5::API,所以很可能是同一个问题。跨度>
    猜你喜欢
    • 2016-04-04
    • 2017-10-02
    • 1970-01-01
    • 2017-06-02
    • 2011-11-16
    • 2021-09-24
    • 2013-12-04
    • 2011-07-14
    • 2020-04-03
    相关资源
    最近更新 更多