首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用H5LTget_attribute_string函数?

如何使用H5LTget_attribute_string函数?
EN

Stack Overflow用户
提问于 2020-10-21 15:56:18
回答 2查看 147关注 0票数 1

我在HDF论坛上问过这个问题,但还没有收到任何答复。所以我想在这里碰碰运气。

我已经在Python (h5py)中创建了一个小的测试文件,并希望使用H5LTget_attribute_string函数从它读取一个属性。但是,我不知道如何使用这个函数。

我的测试文件是这样的。

代码语言:javascript
复制
HDF5 "attr.h5" {
GROUP "/" {
   DATASET "my_dataset" {
      DATATYPE  H5T_STD_I64LE
      DATASPACE  SIMPLE { ( 12 ) / ( 12 ) }
      DATA {
      (0): 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
      }
      ATTRIBUTE "string_attr" {
         DATATYPE  H5T_STRING {
            STRSIZE H5T_VARIABLE;
            STRPAD H5T_STR_NULLTERM;
            CSET H5T_CSET_UTF8;
            CTYPE H5T_C_S1;
         }
         DATASPACE  SCALAR
         DATA {
         (0): "this is a string"
         }
      }
   }
}
}

在我看来,在属性中,我需要分配一个缓冲区,并将缓冲区的地址作为最后一个参数传递,然后H5LT_GET_ATTRIBUTE函数将填充缓冲区。因此,我的第一次尝试就是这样。

代码语言:javascript
复制
#include <assert.h>
#include <stdlib.h>
#include "hdf5.h"
#include "hdf5_hl.h"

int main()
{
    herr_t  status;

    hid_t file_id = H5Fopen("attr.h5", H5F_ACC_RDONLY, H5P_DEFAULT);
    assert(file_id >= 0);
    
    char string[1024];  // assume buffer is large enough;
    
    fprintf(stderr, "string : %s\n", string);
    fprintf(stderr, "pointer: %p\n", string);

    fprintf(stderr, "---- reading attribute ----\n");
    status = H5LTget_attribute_string(file_id, "my_dataset", 
                                      "string_attr", string);
    assert(status >= 0);
    
    fprintf(stderr, "string : %s\n", string);
    fprintf(stderr, "pointer: %p\n", string);
    
    status = H5Fclose(file_id);
    assert(status >= 0);
}

但是,这并没有像预期的那样工作,请参见下面的输出。

代码语言:javascript
复制
string : 
pointer: 0x7ffe3f7ec770
---- reading attribute ----
string : @B�k2V
pointer: 0x7ffe3f7ec770

经过一些搜索和实验,我发现最后一个参数应该是缓冲区的地址。然后,H5LT_GET_ATTRIBUTE函数将使缓冲区指向实际属性值。下面的函数是用警告进行编译的,但是它提供了正确的输出。

代码语言:javascript
复制
#include <assert.h>
#include <stdlib.h>
#include "hdf5.h"
#include "hdf5_hl.h"

int main()
{
    herr_t  status;

    hid_t file_id = H5Fopen("attr.h5", H5F_ACC_RDONLY, H5P_DEFAULT);
    assert(file_id >= 0);
    
    char* string = NULL;
    
    fprintf(stderr, "string : %s\n", string);
    fprintf(stderr, "pointer: %p\n", string);

    fprintf(stderr, "---- reading attribute ----\n");
    status = H5LTget_attribute_string(file_id, "my_dataset", 
                                      "string_attr", &string);
    assert(status >= 0);
    
    fprintf(stderr, "string : %s\n", string);
    fprintf(stderr, "pointer: %p\n", string);
    
    status = H5Fclose(file_id);
    assert(status >= 0);
}

输出

代码语言:javascript
复制
string : (null)
pointer: (nil)
---- reading attribute ----
string : this is a string
pointer: 0x559e9e3d1240

现在我非常高兴像这样使用它,我可以将其转换到**char以消除警告,但我想确定这是预期的行为。理想情况下,文档应该更新。

所以我的问题是:

  1. 第二个例子正确吗?
  2. string缓冲区中的数据有效的时间有多长?也就是说,HDF库何时释放内存?(例如,当文件关闭时)
  3. 在使用字符串数据之前,我应该使用strcpy来复制它吗?
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-10-29 22:21:11

由Scot (来自HDF组)担任尖头

如果使用H5LTget_attribute_string (H5T_VARIABLE)读取可变长度字符串,则不需要分配字符串,只需传入指针,库将处理分配。如果您正在读取一个固定长度的字符串,则需要分配一个“足够大”的字符串。

所以,(1)在我看来,你的第二种方法是可以的。

至于(2)和(3),我敢打赌您应该负责释放缓冲区,所以不需要复制它。但是,可以使用调试器检查库是否正在访问缓冲区,或者更好地使用valgrind查找内存泄漏(当您尝试不访问缓冲区时)。

票数 1
EN

Stack Overflow用户

发布于 2020-10-26 17:30:46

我不做HDF5,但是我做了足够的C来给你一些答案,很高的百分比是你想要的。

  1. 是第二个例子对吗?

是的。首先是因为它返回正确的预期结果,其次是因为任何将填充字符串(又名:char *)的库都需要您提供指针的地址(又名:char **)。

  1. string 缓冲区中的数据有效多长时间?

只要你的程序运行,它是有效的。这个内存已经为您分配了合适的大小,因此它在您的程序的整个生命周期中都是有效的,但是现在是您释放它的责任。如果您需要更多的详细信息,请回复/评论该消息,这样说,我们将帮助您。

  1. 在使用字符串数据之前,我应该使用strcpy 来复制字符串数据吗?

不,你没有把记忆分配给你,你可以把它保存下来:-)

下一步我建议你做:

  • 既然你在他们的医生中发现了问题,你应该联系他们并告诉他们。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64467420

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档