C ++ Call by Ref.с динамической структурой размера, не зная его размера - PullRequest
0 голосов
/ 29 декабря 2011

Мне нужно использовать функцию (часть API), которая сохраняет некоторые запрошенные данные в структуре динамического размера, используя вызов по ссылке.Структура определяется следующим образом - она ​​касается списков контроля доступа либо в версии posix, либо в версии NFS4, но это всего лишь сценарий использования, я полагаю.

    typedef struct my_struct
    {
      unsigned int len;               /* total length of the struct in bytes */
      ...                             /* some other static sized fields */
      unsigned int version;           /* 2 different versions are possible */
      unsigned int amount;            /* number of entries that follow */
      union {
        entry_v1_t entry_v1[1];
        entry_v2_t entry_v2[1];
      }; 
    } my_struct_t;

Есть 2 версии записей, и я знаю, какую из них я получу (v1).И entry_v1_t, и entry_v2_t - это структуры фиксированного (но различного) размера, содержащие только целые числа (поэтому, я думаю, их здесь не стоит объяснять).Теперь мне нужно использовать существующую функцию, чтобы заполнить мою структуру необходимой мне информацией с помощью Call by Reference, подпись выглядит следующим образом, включая комментарии - у меня нет доступа к реализации:

    int get_information(char *pathname, void *ptr);

    /* The ptr parameter must point to a buffer mapped by the my_struct
     * structure. The first four bytes of the buffer must contain its total size.
     */

Итак, дело в том, что я должен выделить память для этой структуры, но не знаю, сколько записей (и, как следствие, общий размер) я должен выделить.Вы когда-нибудь сталкивались с такой ситуацией?

Ответы [ 2 ]

2 голосов
/ 29 декабря 2011

В Windows API есть много таких функций, вы обычно вызываете их с некоторым NULL-указателем, чтобы получить размер буфера, затем снова вызываете с выделенным буфером. В случае, если при следующем вызове размер буфера изменился, функция возвращает ошибку, и вам нужно распределить снова. Таким образом, вы делаете это в цикле while, пока функция не завершится успешно.

Таким образом, ваша get_information должна каким-то образом реализовывать такие механизмы, либо она возвращает false, если буфер мал, либо возвращает свой правильный размер, если ptr равен NULL. Но это только мое предположение.

0 голосов
/ 30 декабря 2011

ОК, я понял, как это работает. Спасибо за ваши идеи и заметки. Я объявил указатель my_struct и выделил минимальное пространство для полей фиксированного размера (5) перед динамическим массивом => 5 * sizeof(unsigned int). Вызов get_information с этим указателем возвращает -1 и устанавливает errno = 28 и strerror(errno) = "No space left on device".

Но он устанавливает для поля my_struct->len требуемый размер, и это, кажется, ответ на мой вопрос - откуда вы знаете? Нет, я могу сначала вызвать get_information с минимальным пространством и выяснить, сколько мне нужно выделить, а затем вызвать его снова с памятью нужного размера, выделенной для успешного получения информации.

Похоже, что циклическое решение имеет смысл в любом случае, и это было бы моей следующей попыткой - поскольку в этом динамическом массиве обычно всего несколько записей.

Спасибо.

...