在阅读Enlightenment's代码时,我发现了一些关于C的事情我不明白。我会粘贴这些线条并解释为什么它不清楚。
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小学标题。
答案 0 :(得分: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。它可能会根据构建选项更改调用约定或导出符号。
答案 1 :(得分:0)
前两个语句是函数指针定义。即获取函数地址的指针变量。
void *
类型可以接受任何有效的指针值或空指针。必须以某种方式跟踪void *
指针所指向的实际类型,以便将void *
正确地类型化为实际类型bahind它。这种方法的常见用途是提供将任意用户类型数据传递给回调函数的方法。这就是两个函数指针的用途。
本声明
Eina_Bool (*hide)(void *data, Evas_Object *o);
表示: hide 是一个指向函数的指针,该函数接受void *
,Evas_Object *
作为参数并返回Eina_Bool
。
请注意,这与略有不同的陈述
大不相同Eina_Bool* reveal(void *data, Evas_Object *o);
这是一个名为reveal
的函数,返回Eina_Bool*
。
答案 2 :(得分:0)
我发现this source定义了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);
这允许运行时根据在线数据选择要调用的函数。