从gui_start_timer函数来看函数指针、指针函数、回调函数
来源:互联网 发布:js循环table tr 编辑:程序博客网 时间:2024/06/05 17:34
/*----------------------------------------------------------------------------Function Pointer: gui_start_timerDescription: One shot timerInput Parameters: count is the delay (Implementation dependent: Normally milliseconds) callback is the function that is called when the timer expiresOutput Parameters: noneReturns: voidRemakrs: NOTE: DO NOT USE UI TIMER IN CRITICAL CASES UI timer will be suspended when LCD backlight is turned off.----------------------------------------------------------------------------*/void (*gui_start_timer) (S32 count, void (*callback) (void)) = NULL;
<pre name="code" class="cpp">void setup_UI_wrappers(void){ gui_start_timer = UI_start_timer;}
typedef void (*gui_timer_funcptr_type)(void *);static gui_timer_funcptr_type UI_timer_callbacks[MAX_UI_TIMERS];
static U8 UI_timer_ID_flags[MAX_UI_TIMERS]; /* 0 means timer is available */
static void *UI_timer_args[MAX_UI_TIMERS];
static void UI_start_timer(S32 count, FuncPtr callback){ UI_start_timer_ex(count, (gui_timer_funcptr_type)<span style="color:#ff0000;">callback</span>, NULL);}
static void UI_start_timer_ex(S32 count, gui_timer_funcptr_type callback, void *arg){ /*----------------------------------------------------------------*/ /* Local Variables */ /*----------------------------------------------------------------*/ S16 i; U8 all_timers_used = 1; /*----------------------------------------------------------------*/ /* Code Body */ /*----------------------------------------------------------------*/ /* check if this function has already been hooked. If yes, remove it */ for (i = 0; i < MAX_UI_TIMERS; i++) { if ((UI_timer_ID_flags[i]) && (UI_timer_callbacks[i] == callback)) { HW_StopTimer(i); UI_timer_callbacks[i] = (gui_timer_funcptr_type)UI_dummy_function; UI_timer_ID_flags[i] = 0; } } /* Check for free timer */ for (i = 0; i < MAX_UI_TIMERS; i++) { if (UI_timer_ID_flags[i] == 0) { all_timers_used = 0; break; } } /* If all timers are used, return */ if (all_timers_used) { return; } /* Hook the callback function and start the OS timer */ UI_timer_callbacks[i] = callback; UI_timer_args[i] = arg; HW_StartTimer((U16)(UI_TIMER_ID_BASE + i), (U32)count, UI_timer_callback, (void*)i); /* Set the timer to busy */ UI_timer_ID_flags[i] = 1;}
void UI_timer_callback(void *arg){ /*----------------------------------------------------------------*/ /* Local Variables */ /*----------------------------------------------------------------*/ S32 timer_id = (S32)arg; /*----------------------------------------------------------------*/ /* Code Body */ /*----------------------------------------------------------------*/ HW_StopTimer(timer_id); UI_timer_ID_flags[timer_id] = 0; mmi_frm_dss_defer_dump_string(MMI_FALSE);if(UI_timer_callbacks[timer_id]){UI_timer_callbacks[timer_id](UI_timer_args[timer_id]);} mmi_frm_dss_defer_dump_string(MMI_TRUE);}
void (*gui_start_timer) (S32 count, void (*callback) (void)) = NULL;这是一个函数指针。
判断是指针函数还是函数指针重点落在后面的两个字上。
指针函数本质上还是函数,只是函数的返回值为某种类型的指针。例:
int *f(x,y);
或者另外下面的写法:
int* f(x,y);
(int*) f(x,y);
函数指针的本质是指针,只是它是一个指向函数的指针变量。
int (*f)(x,y);
void (*f)(x,y);
由UI_timer_callback()函数里面下面这一句:
if(UI_timer_callbacks[timer_id])
{
UI_timer_callbacks[timer_id](UI_timer_args[timer_id]);
}
我们可以知道函数指针的调用方式。
例如:
void (*fptr)();
把函数的地址赋值给函数指针,可以采用下面两种形式:
fptr=&Function;
fptr=Function;
取地址运算符&不是必需的,因为单单一个函数标识符就标号表示了它的地址,如果是函数调用,还必须包含一个圆括号括起来的参数表。
可以采用如下两种方式来通过指针调用函数:
x=(*fptr)();
x=fptr();
以上例如为网上引用来的。建议程序员调用函数指针的时候都采用第一种方式,这样增加代码的易读性。
===========================================================================================
函数指针和指针函数弄明白后,通过gui_start_timer这个例子,我们还可以看到回调函数的实现方式。
UI_timer_callbacks其实是UI_start_timer()函数中回调函数参数的最终实现。
所以回调函数其实就是以函数指针的形式用指针调用函数来实现的。
在网上搜到一个很好的案例:
一般需要定义一个函数指针类型
typedef
int
(*function_pointer_t) (
int
arg1,
int
arg2 );
然后,定义函数指针变量
function_pointer_t fp_invoker = 0;
函数指针可以动态改变内容,改变调用对象,假设有两个函数
int
function_sum(
int
arg1,
int
arg2 )
{
return
arg1+arg2;
}
int
function_sub(
int
arg1,
int
arg2 )
{
return
arg1-arg2;
}
注意到两个函数的原型与函数指针类型是一致的。以下是调用
fp_invoker = function_sum;
// 直接用函数名赋值即可
fp_invoker(1,2);
// 调用时,可以认为函数指针便是函数名,此时调用加法
fp_invoker = function_sub;
// 同理,切换到减法
fp_invoker(1,2);
// 调用减法
以上都是直观的用法,通常函数指针用于回调,即下层函数先将函数指针内容保存起来,处理结束后,再调用。此时要注意首先检查函数指针内容是否为空。
if
( fp_invoker ){
fp_invoker( arg1, arg2 );
}
mtk的这个调用稍微复杂一点:
UI_timer_callbacks[timer_id](UI_timer_args[timer_id]);
因为函数指针的参数是一个指针函数。
- 从gui_start_timer函数来看函数指针、指针函数、回调函数
- 指针函数 、函数指针 、 回调函数
- 指针函数、函数指针、回调函数
- 回调函数 函数指针
- 函数指针回调函数
- 函数指针回调函数
- 函数指针 回调函数
- 回调函数,函数指针
- 指针 下:函数指针,函数指针数组,函数指针数组的指针,回调函数详解
- 函数指针、指针函数以及回调函数
- 指针函数、函数指针和回调函数
- 函数指针和回调函数浅学
- 函数指针和回调函数
- 函数指针及回调函数
- 函数指针与回调函数
- 回调函数和函数指针
- 函数指针和回调函数
- 回调函数:函数指针(一)
- selenium_webdriver(python)获取元素属性值,浏览器窗口控制、网页前进后退,title/url打印
- C++重载运算操作符示例
- VC++信息安全编程(13)Windows2000/xp/vista/7磁盘扇区读写技术
- 常用命令
- WIN32多线程编程( CreateThread 版本)
- 从gui_start_timer函数来看函数指针、指针函数、回调函数
- java中this关键词
- UDP 通信 例子
- 正则表达式(Regular Expression)基本语法
- 数据仓库中拉动查询性能的三驾马车
- Unity3D之AssetBundle资源加载封装
- Android中动态drawable样式
- list<string>转换成list<int>类型
- 如何让struts2和servlet的共存