Итерация по дизайну буфера - PullRequest
0 голосов
/ 25 марта 2019

Я работаю над приложением, управляемым событиями, и хотел бы предоставить API высокого уровня для низкоуровневого интерфейса системы.В настоящее время я сомневаюсь, как распространить errno вниз по стеку вызовов.Вот мой текущий API

typedef struct watcher_t watcher_t;

typedef struct event_iterator_t event_iterator_t;

event_iterator_t *poll_events(watcher_t *watcher, 
                              int poll_timeout_millis, 
                              void *buffer);

const char* take_event_path(void *event_buffer, 
                            event_iterator_t *iterator);

Проблема в том, что у вызывающей стороны событий опроса в настоящее время нет другого выбора, кроме как использовать errno.Я имею в виду

#include <errno.h>

void *buf = //...
watcher_t *watcher_ptr = //...
event_iterator_t * iterator_ptr = poll_events(watcher_ptr, 1000, buf);
if(iterator_ptr == NULL){
   perror("Error while getting iterator");
}

Я не уверен, что такой подход широко используется.Есть ли какие-либо преимущества в объявлении типа результата int и event_iterator_t ** в качестве параметра out.

int poll_events(watcher_t *watcher, 
               int poll_timeout_millis, 
               void *buffer,
               event_iterator_t **out);

Ответы [ 2 ]

2 голосов
/ 25 марта 2019

Если вы хотите распространить ошибку, вы: 1. Установите тип возврата равным ошибке / 0. Затем сделайте, как указано в вашем втором сценарии. 2. Если для вас достаточно установить значение errno, вы можете продолжать возвращать NULL, если все становится мрачно при правильной настройке errno.

Единственное, что вам следует придерживаться, это делать это одинаково через API и делать возможным указание ошибки всегда и делать это одинаково.

2 голосов
/ 25 марта 2019

Я не уверен, что такой подход широко используется.Есть ли какие-либо преимущества объявления типа результата как int, а event_iterator_t ** как параметра out.

Оба подхода являются общими.Но когда функция возвращает int код результата, становится проще быть потокобезопасным, а API легче документировать.

Я советую использовать следующий подход:

  • вернуть int в качестве кода результата
  • передать обработчик контекста в качестве первого параметра, который будет содержать наблюдатели, итератор и т. д.

Пример:

int api_init_context(api_context_t *ctx);
int api_add_watcher(api_context_t *ctx, watcher_t *watcher);
int api_poll_events(api_context_t *ctx, int poll_timeout_millis, void *buffer);
int api_take_event_path(api_context_t *ctx, void *event_buffer);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...