我正在开发一个事件驱动的应用程序,并希望为系统的低级接口提供一个高级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);
我不确定这种方法是否常用。将结果类型声明为 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);
如果要传播错误,请:1. 将返回类型设置为错误/0。然后按照第二个方案中列出的操作。2.如果设置errno对您来说已经足够了,如果在适当设置errno时情况变得严峻,您可以坚持返回NULL。
您唯一应该坚持的是通过 API 以相同的方式执行此操作,并始终指示错误并以相同的方式执行。