我在HDF论坛上问过这个问题,但还没有收到任何答复。所以我想在这里碰碰运气。
我已经在Python (h5py)中创建了一个小的测试文件,并希望使用H5LTget_attribute_string函数从它读取一个属性。但是,我不知道如何使用这个函数。
我的测试文件是这样的。
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函数将填充缓冲区。因此,我的第一次尝试就是这样。
#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);
}但是,这并没有像预期的那样工作,请参见下面的输出。
string :
pointer: 0x7ffe3f7ec770
---- reading attribute ----
string : @B�k2V
pointer: 0x7ffe3f7ec770经过一些搜索和实验,我发现最后一个参数应该是缓冲区的地址。然后,H5LT_GET_ATTRIBUTE函数将使缓冲区指向实际属性值。下面的函数是用警告进行编译的,但是它提供了正确的输出。
#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);
}输出
string : (null)
pointer: (nil)
---- reading attribute ----
string : this is a string
pointer: 0x559e9e3d1240现在我非常高兴像这样使用它,我可以将其转换到**char以消除警告,但我想确定这是预期的行为。理想情况下,文档应该更新。
所以我的问题是:
string缓冲区中的数据有效的时间有多长?也就是说,HDF库何时释放内存?(例如,当文件关闭时)strcpy来复制它吗?发布于 2020-10-29 22:21:11
由Scot (来自HDF组)担任尖头:
如果使用H5LTget_attribute_string (H5T_VARIABLE)读取可变长度字符串,则不需要分配字符串,只需传入指针,库将处理分配。如果您正在读取一个固定长度的字符串,则需要分配一个“足够大”的字符串。
所以,(1)在我看来,你的第二种方法是可以的。
至于(2)和(3),我敢打赌您应该负责释放缓冲区,所以不需要复制它。但是,可以使用调试器检查库是否正在访问缓冲区,或者更好地使用valgrind查找内存泄漏(当您尝试不访问缓冲区时)。
发布于 2020-10-26 17:30:46
我不做HDF5,但是我做了足够的C来给你一些答案,很高的百分比是你想要的。
是的。首先是因为它返回正确的预期结果,其次是因为任何将填充字符串(又名:char *)的库都需要您提供指针的地址(又名:char **)。
string 缓冲区中的数据有效多长时间?只要你的程序运行,它是有效的。这个内存已经为您分配了合适的大小,因此它在您的程序的整个生命周期中都是有效的,但是现在是您释放它的责任。如果您需要更多的详细信息,请回复/评论该消息,这样说,我们将帮助您。
strcpy 来复制字符串数据吗?不,你没有把记忆分配给你,你可以把它保存下来:-)
下一步我建议你做:
https://stackoverflow.com/questions/64467420
复制相似问题