英文:
what this syntax in libev C language?
问题
在阅读libev文档时,我发现了一些C代码,其中语法相当奇怪。
static void
stdin_cb (EV_P_ ev_io *w, int revents)
{
puts ("stdin ready");
// for one-shot events, one must manually stop the watcher
// with its corresponding stop function.
ev_io_stop (EV_A_ w);
// this causes all nested ev_run's to stop iterating
ev_break (EV_A_ EVBREAK_ALL);
}
我不太确定这里的 EV_P_
是什么,有人可以帮忙解释一下吗?
我已经尝试了谷歌搜索C方法签名的语法,但没有找到合适的匹配项。
英文:
While reading the doc in libev I find some C code of which the syntax is quite weird.
static void
stdin_cb (EV_P_ ev_io *w, int revents)
{
puts ("stdin ready");
// for one-shot events, one must manually stop the watcher
// with its corresponding stop function.
ev_io_stop (EV_A_ w);
// this causes all nested ev_run's to stop iterating
ev_break (EV_A_ EVBREAK_ALL);
}
I'm not sure what the EV_P_
is here, could anyone help explain it to me?
I have tried to google the syntax of method signature in C but no good matches.
答案1
得分: 2
请看 ev.h:
#if EV_MULTIPLICITY
struct ev_loop;
# define EV_P struct ev_loop *loop /* a loop as sole parameter in a declaration */
# define EV_P_ EV_P, /* a loop as first of multiple parameters */
...
#else
# define EV_P void
# define EV_P_
...
#endif
因此,这行代码:
stdin_cb (EV_P_ ev_io *w, int revents)
展开为:
stdin_cb (struct ev_loop *loop, ev_io *w, int revents)
或者
stdin_cb (ev_io *w, int revents)
这取决于 EV_MULTIPLICITY
的值。
正如 @Shawn 指出的那样,有一个 宏魔术部分 解释了它:
> EV_P, EV_P_
>
> 这为函数提供了循环参数,如果需要的话("ev loop parameter")。当这是唯一的参数时使用 EV_P 形式,当后面还有其他参数时使用 EV_P_ 形式。示例:
>
> // 这是如何声明 ev_unref 的方式
> static void ev_unref (EV_P);
>
> // 这是你可以声明典型回调的方式
> static void cb (EV_P_ ev_timer *w, int revents)
>
> 它声明了一个类型为 struct ev_loop * 的参数 loop,非常适合与 EV_A 一起使用。
英文:
See ev.h:
#if EV_MULTIPLICITY
struct ev_loop;
# define EV_P struct ev_loop *loop /* a loop as sole parameter in a declaration */
# define EV_P_ EV_P, /* a loop as first of multiple parameters */
...
#else
# define EV_P void
# define EV_P_
...
#endif
Therefore the line
stdin_cb (EV_P_ ev_io *w, int revents)
expands to
stdin_cb (struct ev_loop *loop, ev_io *w, int revents)
or
stdin_cb (ev_io *w, int revents)
depending on the value of EV_MULTIPLICITY
As pointed out by @Shawn, there is a Macro magic section that explains it:
> EV_P, EV_P_
>
> This provides the loop parameter for functions, if one is required ("ev loop parameter"). The EV_P form is used when this is the sole parameter, EV_P_ is used when other parameters are following. Example:
>
> // this is how ev_unref is being declared
> static void ev_unref (EV_P);
>
> // this is how you can declare your typical callback
> static void cb (EV_P_ ev_timer *w, int revents)
>
> It declares a parameter loop of type struct ev_loop *, quite suitable for use with EV_A.
答案2
得分: -1
EV_P_
是一个宏,表示“一个作为参数的 ev 循环,加上一个逗号”。
EV_A_
是一个宏,表示“一个作为参数的 ev 循环,加上一个逗号”。
它们在定义如下:
#define EV_P struct ev_loop *loop /* 声明中作为唯一参数的循环 */
#define EV_P_ EV_P, /* 作为多个参数中的第一个参数 */
#define EV_A loop /* 函数调用中作为唯一参数的循环 */
#define EV_A_ EV_A, /* 作为多个参数中的第一个参数 */
或者如下:
# define EV_P void
# define EV_P_
# define EV_A
# define EV_A_
这意味着:
static void stdin_cb( EV_P_ ev_io *w, int revents ) {
puts( "stdin ready" );
ev_io_stop( EV_A_ w );
ev_break( EV_A_ EVBREAK_ALL );
}
等同于
static void stdin_cb( struct ev_loop *loop, ev_io *w, int revents ) {
puts( "stdin ready" );
ev_io_stop( loop, w );
ev_break( loop, EVBREAK_ALL );
}
或者
static void stdin_cb( ev_io *w, int revents ) {
puts( "stdin ready" );
ev_io_stop( w );
ev_break( EVBREAK_ALL );
}
哪一组 #define
指令被使用是可配置的。
如果设置了并且非零 EV_MULTIPLICITY
,则使用第一组。第一组允许在同一程序中使用多个 ev 循环(可能在不同的线程中)。
如果未设置或为零,将使用第二组。第二组更高效,因为它使用全局变量而不是将结构传递给每个与 ev 相关的函数。但是程序只能有一个事件循环。
英文:
EV_P_
is a macro which means "an ev loop as a parameter, plus a comma".
EV_A_
is a macro which means "an ev loop as an argument, plus a comma".
They are defined as
#define EV_P struct ev_loop *loop /* a loop as sole parameter in a declaration */
#define EV_P_ EV_P, /* a loop as first of multiple parameters */
#define EV_A loop /* a loop as sole argument to a function call */
#define EV_A_ EV_A, /* a loop as first of multiple arguments */
or as
# define EV_P void
# define EV_P_
# define EV_A
# define EV_A_
(Some whitespace was removed so it would fit better.)
This means
static void stdin_cb( EV_P_ ev_io *w, int revents ) {
puts( "stdin ready" );
ev_io_stop( EV_A_ w );
ev_break( EV_A_ EVBREAK_ALL );
}
is equivalent to
static void stdin_cb( struct ev_loop *loop, ev_io *w, int revents ) {
puts( "stdin ready" );
ev_io_stop( loop, w );
ev_break( loop, EVBREAK_ALL );
}
or
static void stdin_cb( ev_io *w, int revents ) {
puts( "stdin ready" );
ev_io_stop( w );
ev_break( EVBREAK_ALL );
}
Which set of #define
directives is used is configurable.
If EV_MULTIPLICITY
is set and nonzero, the first set is used. The first set allows multiple ev loops to be used in the same program. (Perhaps in different threads.)
If EV_MULTIPLICITY
is unset or zero, the second set is used. The second is more efficient since it uses global variables instead of passing a structure to every ev-related function. But the program can only have one event loop.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论