Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2372045
  • 博文数量: 473
  • 博客积分: 12252
  • 博客等级: 上将
  • 技术积分: 4307
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-12 10:02
文章分类

全部博文(473)

文章存档

2012年(8)

2011年(63)

2010年(73)

2009年(231)

2008年(98)

分类: C/C++

2009-09-25 08:59:50

回调函数原理

声明CALLBACK  

(calling)机制从汇编时代起已大量使用:准一段成的代用者可以随至此段代的起始地址,行完后再返回跳转时的后地址。CPU此准成的用指令,可以压栈护现场束后从堆现场地址,以便自返回。借堆护现场,它使用者和被者可以互不相,于是才有了后来的函数和构件.  

用机制并非完美。回函数就是一例。例如,写一个快速排序函数供他人用,其中必包含比大小。麻来了:此并不知要比的是何数据--整数、浮点数、字符串?于是只好数据制作一个不同的排序函数。更通行的法是在函数参数中列一个回函数地址,并通知用者:君需自己准一个比函数,其中包含两个指针类参数,函数要比此二指所指数据之大小,并由函数返回值说明比较结果。排序函数借此用者提供的函数来比大小,借指针传递参数,可以全然不管所比的数据型。被用者回头调用者的函数(咬嘴的),故称其callback)。

Windows统还包含着另一种更广泛的回机制,即消息机制。消息本是Windows的基本控制手段,乍看与函数用无关,其是一种相的函数用。送消息的目的是通知收方

运行一段先准好的代,相当于用一个函数。消息所附WParamLParam相当于函数的参数,只不比普通参数更通用一些。用程序可以主动发送消息,更多情况下是坐等  Windows送消息。一旦消息入所属消息列,便趣的那些,跳行相的消息理代。操作系本是为应用程序服,由用程序来用。而用程序一旦启,却要反等待操作系用。分明也是一种回,或者是一种广。其用程序之也可以形成种回。假如B收到A来的消息,启了一段代,其中又向A送消息,就形成了回种回较隐蔽,弄不好会搞成递归调用,若缺少止条件,将会不已,直至把程序搞。若是故意写成此递归调用,并止条件,倒是很有意思。但种程序构太蔽,除非十分必要,是不用好。

利用消息也可以构成狭。上面所排序函数一例,可以把回函数地址成窗口handle。如此,当需要比数据大小,不是去用回函数,而是借API函数SendMessage   向指定窗口送消息。收到消息方负责数据大小,把比较结果通消息本身的返回值传给消息送方。所实现的功能与回函数并无不同。当然,此例中改消息属画蛇添脚,反倒把程序搞得很慢。但其他情况下并非是如此,特是需要异步送消息是一种选择。假如回函数中包含文件理之的低速理,用方等不得,需要把同步用改异步用,去启一个独的线程,然后行后,其余的事让线程慢慢去做。一个替代法是借   API函数PostMessage送一个异步消息,然后立即行后要比自己搞个线程省事多,而且更安全。

如今我是活在一个object代。只要与程有关,无何事都离不开object。但object并未消除回,反而把它发扬光大,弄得到都是,只不大都以事件(event)的身份出嵌在某个构之中,得更正,更容易被人接受。用程序要使用某个构件,要先弄清构件的属性、方法和事件,然后构件属性赋值,在适当的用适当的构件方法,理例程,以构件代用。何事件?它不是一个指向事件例程的地址,与回数地址没什么区,此种回方式比传统函数要高明多。首先,它把人不太舒服的回函数一种自然而然的理例程,使程者顿觉。再者,地址是一个危西,用好了可使程序加速,用不好处处是陷阱,程序随都会崩程方式是想法把地址藏起来(藏比较彻底的如VBJava),其代价是降低了程序效率。事件例程使程者无需直接操作地址,但并不会使程序减速。

 

自定义回调函数

函数是不能用的函数;通将回函数的地址传给调用者从而实现调用。函数使用是必要的,在我想通一个一接口实现不同的内容,这时用回掉函数非常合适。比如,我们为几个不同的设备写了不同的示函数:void TVshow(); void ComputerShow(); void NoteBookShow()...等等。是我想用一个一的示函数,我们这时就可以用回掉函数了。

    void show(void (*ptr)());

使用根据所入的参数不同而用不同的回函数。

不同的言可能有不同的法,下面一个c言中回函数的例子,其中一个回函数不参数,另一个回函数参数。

例子1

 

//Test.c

 

#include

#include

 

int Test1()

{

   int i;

   for (i=0; i<30; i++)

   {

     printf("The %d th charactor is: %c\n", i, (char)('a' + i%26));

    }

   return 0;

}

int Test2(int num)

{

   int i;

   for (i=0; i

   {

    printf("The %d th charactor is: %c\n", i, (char)('a' + i%26));

    }

   return 0;

}

 

void Caller1(void (*ptr)())//指向函数的指作函数参数

{

   (*ptr)();

}

void Caller2(int n, int (*ptr)())//指向函数的指作函数参数,里第一个参数是指向函数的指的,

{ //不能写成void Caller2(int (*ptr)(int n))这样的定义语错误

   (*ptr)(n);

   return;

}

int main()

{

   printf("************************\n");

   Caller1(Test1); //相当于Test2();

   printf("&&&&&&************************\n");

   Caller2(30, Test2); //相当于Test2(30);

   return 0;

}

 

以上通将回函数的地址传给调用者从而实现调用,但是需要注意的是参回函数的用法。要实现,必首先定函数指。函数指的定义这里稍微提一下。比如: int (*ptr)(); ptr是一个函数指,其中(*ptr)的括号不能省略,因括号的高于星号,那就成了一个返回整型的函数声明了。

=================================

转载地址:

: 狐狸认为, 函数实现函数只是附功能之一, 最主要是提供了一种代码动态嵌入的手段, 实现函数内部中断的一种方式.

文章出

阅读(1492) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~