Структура HDF5 с массивом указателей

Я пытаюсь написать файл HDF5 со структурой, которая содержит int и float *

typedef struct s1_t {
int    a;
float *b;
} s1_t;

Тем не менее, после размещения float * и ввода значений в него, я все еще не могу вывести данные в моем файле hdf5. Я считаю, что это потому, что функция записи предполагает, что составной тип данных является смежным, когда динамически распределенный массив не будет. Есть ли способ обойти эту проблему, все еще используя массив указателей?

    /*
* This example shows how to create a compound data type with an array member,
* and write an array which has the compound data type to the file.
*/
#include "stdio.h"#include "stdlib.h"#include "hdf5.h"
#define FILE          "DSwith_array_member.h5"#define DATASETNAME   "ArrayOfStructures"#define LENGTH        10
#define RANK          1
#define ARRAY_RANK    1
#define ARRAY_DIM     3

int
main(void)
{

/* First structure  and dataset*/
typedef struct s1_t {
int    a;
//float  b[ARRAY_DIM];
float *b;
} s1_t;
s1_t       s1[LENGTH];

hid_t      s1_tid;     /* File datatype identifier */
hid_t      array_tid; /* Array datatype handle */
hid_t      file, dataset, space; /* Handles */
herr_t     status;
hsize_t    dim[] = {LENGTH};   /* Dataspace dimensions */
hsize_t    array_dim[] = {ARRAY_DIM};   /* Array dimensions */

int        i, j;

/*
* Initialize the data
*/
for (i = 0; i< LENGTH; i++) {
s1[i].a = i;
s1[i].b = (float*)calloc(ARRAY_DIM, sizeof(float));
for (j = 0; j < ARRAY_DIM; j++) {
s1[i].b[j] = i+j;
}
}

/*
* Create the data space.
*/
space = H5Screate_simple(RANK, dim, NULL);

/*
* Create the file.
*/
file = H5Fcreate(FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);

/*
* Create the array data type.
*/
array_tid = H5Tarray_create(H5T_NATIVE_FLOAT, ARRAY_RANK, array_dim);

/*
* Create the memory data type.
*/
s1_tid = H5Tcreate (H5T_COMPOUND, sizeof(s1_t));
H5Tinsert(s1_tid, "a_name", HOFFSET(s1_t, a), H5T_NATIVE_INT);
H5Tinsert(s1_tid, "b_name", HOFFSET(s1_t, b), array_tid);

/*
* Create the dataset.
*/
dataset = H5Dcreate(file, DATASETNAME, s1_tid, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);

/*
* Wtite data to the dataset;
*/
status = H5Dwrite(dataset, s1_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, s1);

/*
* Release resources
*/
H5Tclose(s1_tid);
H5Tclose(array_tid);
H5Sclose(space);
H5Dclose(dataset);
H5Fclose(file);return 0;
}

6

Решение

Вы правы. Изменение вашей структуры на

typedef struct s1_t {
int   a;
float b[ARRAY_DIM];
} s1_t;

будет работать, но я думаю, вы это знаете.

Я вижу два решения:

  1. Используйте для записи временный буфер, как массив описанной выше структуры.
  2. Использование массива переменной длины вместо массива для b_name,

Пример использования массива переменной длины для b_name

#include "stdio.h"#include "stdlib.h"#include "hdf5.h"
#define FILE          "DSwith_array_member.h5"#define DATASETNAME   "ArrayOfStructures"#define LENGTH        10
#define RANK          1
#define ARRAY_RANK    1
#define ARRAY_DIM     3

typedef struct s1_t {
int    a;
float *b;
} s1_t;

typedef struct s1_buffer_t {
int   a;
hvl_t b;
} s1_buffer_t;

int main(void)
{
s1_t       s1[LENGTH];
hid_t      s1_tid;                          /* File datatype identifier */
hid_t      file, dataset, space, vlen_tid;  /* Handles */
hsize_t    dim[] = {LENGTH};                /* Dataspace dimensions */
int        i, j;
s1_buffer_t s1_buffer[LENGTH];
for (i = 0; i< LENGTH; i++) {
s1[i].a = i;
s1[i].b = (float*)calloc(ARRAY_DIM, sizeof(float));
for (j = 0; j < ARRAY_DIM; j++) {
s1[i].b[j] = i+j;
}
}
space = H5Screate_simple(RANK, dim, NULL);
file = H5Fcreate(FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
vlen_tid = H5Tvlen_create(H5T_NATIVE_FLOAT);
s1_tid = H5Tcreate(H5T_COMPOUND, sizeof(s1_buffer_t));
H5Tinsert(s1_tid, "a_name", HOFFSET(s1_t, a), H5T_NATIVE_INT);
H5Tinsert(s1_tid, "b_name", HOFFSET(s1_t, b), vlen_tid);
dataset = H5Dcreate(file, DATASETNAME, s1_tid, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
for (i = 0; i < LENGTH; ++i)
{
s1_buffer[i].a = s1[i].a;
s1_buffer[i].b.len = ARRAY_DIM;
s1_buffer[i].b.p = s1[i].b;
}
H5Dwrite(dataset, s1_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, s1_buffer);
H5Tclose(s1_tid);
H5Tclose(vlen_tid);
H5Sclose(space);
H5Dclose(dataset);
H5Fclose(file);
return 0;
}

Как видите, вам все еще нужен временный буфер, но, по крайней мере, он должен хранить только указатели ( b указатели от s1) а не массивы размера ARRAY_DIM как было бы в случае с решением 1 выше.

7

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]