0

在阅读Enlightenment的代码时,我发现关于CI的一些东西不明白。我将粘贴这些线条并解释为什么我不清楚。

Eina_Bool (*hide)(void *data, Evas_Object *o);
void (*del)(void *data, Evas_Object *o);

在这个上,括号之间的指针值在返回值之后意味着什么?另外,请注意,这两个函数的第一个参数都是void *data. 这是否意味着您可以将指向任何类型数据的指针传递给函数?

EAPI Ecore_X_Window elm_win_xwindow_get(const Evas_Object *obj);

API 上的几乎所有函数都以EAPI. 这意味着什么?它是一种命名空间吗?我在哪里可以找到有关这方面的一些信息?

还要注意他们如何使用其中一个库:Elementary

EAPI_MAIN int elm_main(int argc, char **argv) {
    // CODE
}
ELM_MAIN()

您无需使用 main 函数,而是将 elm_main 再次与那些大写标志一起使用:EAPI_MAIN。就在函数之后,ELM_MAIN()没有分号就很奇怪。

如果你们向我解释一下我第一次看到他们时看起来很奇怪的所有这些,我将不胜感激。

注意:我粘贴的所有示例都来自elm_win.h基本头文件。

4

3 回答 3

2

您在此处显示的行是函数指针变量的声明。

一行表格:

int (*foo)(int x)

例如,声明一个名为 foo 的变量,它可以保存一个函数(地址),该函数接受一个整数参数 ( x) 并返回一个整数。如果你声明一个这样的函数:

int twice( int x )
{
    return x*2;
}

您可以将该函数(的地址)分配给变量 foo。

foo = twice;

然后你可以twice通过指针调用函数:

int result = foo( 3 );

result现在将包含 6 个)

这样做的通常原因是你知道你想在代码中的某个点调用某个函数,但究竟哪个函数取决于其他代码。如果您调用了函数process_A,并且process_B可以将其中一个分配给函数变量:

int (*process)(int x);
process = using_b ? process_B : process_A;
... more code ...
result = process( some_value );

这里的结果设置为由process_A或计算的值process_B,具体取决于分配给哪个process

当然,您可以在调用点使用条件,但是选择函数并将其(或者更确切地说它的地址)存储在变量中会导致更高效和(更重要的是)更清晰的代码。

至于EAPI符号......我不知道启蒙,但我希望这只是标题中的一个宏#defined。它可能会根据构建选项更改调用约定或导出符号。

于 2012-10-20T18:00:13.847 回答
0

Those first two statements are function pointer definitions. I.e. pointer variables that take the address of a function.

A type of void * can accept any valid pointer value or a null pointer. It's mandatory to somehow keep track of what's the actual type a void * pointer points to, to properly typecast the void * to the actual type bahind it. The common use for this is providing means to pass arbitrary user typed data to callback functions. And that's what the two function pointers are for.

This statement

Eina_Bool (*hide)(void *data, Evas_Object *o);

means: hide is a pointer to a function that accepts as parameters a void *, a Evas_Object * and returns a Eina_Bool.

Note that this substantially different to the subtely different statement

Eina_Bool* reveal(void *data, Evas_Object *o);

Which would be a function named reveal returning a Eina_Bool*.

于 2012-10-20T17:50:37.133 回答
0

我发现这个来源定义EAPI

#ifdef _WIN32
# ifdef EFL_EFX_BUILD
#  ifdef DLL_EXPORT
#   define EAPI __declspec(dllexport)
#  else /* ifdef DLL_EXPORT */
#   define EAPI
#  endif /* ! DLL_EXPORT */
# else /* ifdef EFL_BUILD */
#  define EAPI __declspec(dllimport)
# endif /* ! EFL_BUILD */
#else /* ifdef _WIN32 */
# ifdef __GNUC__
#  if __GNUC__ >= 4
#   define EAPI __attribute__ ((visibility("default")))
#  else /* if __GNUC__ >= 4 */
#   define EAPI
#  endif /* if __GNUC__ >= 4 */
# else /* ifdef __GNUC__ */
#  define EAPI
# endif /* ifdef __GNUC__ */
#endif /* ! _WIN32 */

这些都是编译器标志。

现在,关于您的hide问题del;这些不是函数,而是函数指针。也就是说,如果你取消引用del,你会得到这种类型的函数:

void del_impl(void *data, Evas_Object *o);

这允许运行时根据在线数据选择调用哪个函数。

于 2012-10-20T17:52:20.933 回答