遍历缓冲区设计问题

Iterating through buffer design issue

我正在开发一个事件驱动的应用程序,想为系统的低级接口提供一个高级 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 ** 声明为输出参数有什么好处吗?

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

I'm not sure if such approach commonly used. Is there any benefits of declaring the result type as int and an event_iterator_t ** as out parameter.

这两种方法都很常见。但是当函数 return 的结果代码是 int 时,它更容易成为线程安全的并且 API 更容易记录。

我建议使用以下方法:

  • return 一个整数作为结果代码
  • 将上下文处理程序作为第一个参数传递,其中将包含观察器、迭代器等。

示例:

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);

如果您想传播错误,您: 1. 将 return 类型设置为 error/0。然后按照你的第二个场景中列出的去做。 2. 如果设置 errno 对你来说足够了,如果在适当设置 errno 时情况变得严峻,你可以坚持 returning NULL。

你应该坚持的唯一一件事就是通过 API 以同样的方式做,并且可以指示错误 always 并且做同样的事情方法。