详解C语言中的回调函数
C语言带参数的回调函数怎么传参函数——函数输出参数不定参函数函数指针(回调函数转移

C语言带参数的回调函数怎么传参函数——函数输出参数不定参函数函数指针(回调函数转移C语言中的回调函数是指将一个函数作为参数传递给另一个函数,并且在后者内部调用前者。
带参数的回调函数可以通过几种方式传递参数,包括函数,函数输出参数、不定参函数、函数指针等。
一、函数,函数输出参数:在C语言中,函数是无法直接返回数组类型的。
但是可以通过传递指向数组的指针作为参数,并在回调函数中修改该数组来实现这一功能。
具体实现如下:```c#include <stdio.h>#include <stdlib.h>void callback_func(int* arr, int length)for (int i = 0; i < length; i++)arr[i] = i;}void caller_func(void(*callback)(int*, int), int* arr, int length)callback(arr, length);int maicaller_func(callback_func, arr, 5);for (int i = 0; i < 5; i++)printf("%d ", arr[i]);}return 0;```在以上代码中,callback_func函数接收一个指向int类型的数组和数组长度作为参数,并将数组的值修改为0到length-1的连续整数。
caller_func函数接收一个回调函数和一个数组作为参数,并调用该回调函数,并将数组作为参数传递给回调函数。
二、不定参函数:不定参数函数是指函数的参数个数可变的情况。
在C语言中,可以使用stdarg.h头文件中提供的宏和函数来实现不定参函数的参数传递。
具体实现如下:```c#include <stdio.h>#include <stdarg.h>int sum(int num, ...)int result = 0;va_start(args, num);for (int i = 0; i < num; i++)int val = va_arg(args, int);result += val;}va_end(args);return result;int maiint sum_result = sum(5, 1, 2, 3, 4, 5);printf("Sum: %d", sum_result);return 0;```在以上代码中,sum函数接收一个整数num和不定个数的整数参数,利用stdarg.h头文件中的宏和函数来遍历参数列表,将所有参数进行求和后返回。
c语言callback回调函数

c语言callback回调函数C语言的回调函数是一种非常重要的编程技术,它可以实现程序的灵活性和可扩展性,同时也可以提高代码的重用性和可维护性。
本文将详细介绍C语言的回调函数,包括定义、用法、实现原理以及常见应用等方面。
一、回调函数的定义回调函数是指在一个函数中调用另一个函数,并将其作为参数传递给调用函数的一种技术。
在C语言中,回调函数通常是指一个函数指针,它指向一个函数,并可以作为参数传递给另一个函数。
回调函数的定义格式如下:```返回值类型 (*函数名)(参数列表);```其中,返回值类型是指回调函数返回的值的类型,函数名是指回调函数的名称,参数列表是指回调函数接收的参数列表。
例如,下面是一个简单的回调函数定义示例:```int (*callback)(int, int);```这个回调函数的返回值类型为int,函数名为callback,参数列表包括两个int类型的参数。
二、回调函数的用法回调函数主要用于实现程序的动态扩展和灵活性。
它可以使程序在运行时根据需要动态地调用指定的函数,而不必在编译时就确定执行的函数。
这种灵活性使得回调函数在很多编程场景中都得到了广泛应用。
例如,在GUI编程中,回调函数通常用于响应用户的操作,例如单击按钮、拖动窗口等事件。
程序可以根据用户的操作动态地调用相应的回调函数,从而实现交互式的界面效果。
在网络编程中,回调函数也经常被用于处理异步操作,例如网络连接、数据接收等操作。
程序可以将回调函数作为参数传递给异步操作函数,当异步操作完成时,程序会自动调用相应的回调函数,从而实现对异步操作的处理。
三、回调函数的实现原理回调函数的实现原理是基于函数指针的机制。
在C语言中,函数名就是一个指向函数体的指针,它可以被赋值给另一个指向函数的指针变量。
回调函数的本质就是将一个函数的指针作为参数传递给另一个函数,并在需要时调用该函数指针所指向的函数。
例如,下面是一个简单的回调函数示例:```int add(int a, int b) {return a + b;}int sub(int a, int b) {return a - b;}int calc(int a, int b, int (*callback)(int, int)) {return callback(a, b);}int main() {int a = 10, b = 5;printf("add: %d\n", calc(a, b, add));printf("sub: %d\n", calc(a, b, sub));return 0;}```这个程序定义了两个函数add和sub,它们分别实现了加法和减法运算。
c语言 typedef 回调函数

c语言 typedef 回调函数在C语言中,typedef可以用来为函数指针定义别名,这在回调函数中非常有用。
回调函数是指在某个特定事件发生时由另一个函数调用的函数。
通过使用typedef,我们可以为回调函数定义一个更加简洁的别名,使得代码更易读和易维护。
首先,我们需要定义回调函数的原型,然后使用typedef为这个函数指针定义一个别名。
例如:c.typedef int (CallbackFunction)(int, int);这里,我们定义了一个名为CallbackFunction的别名,它表示一个返回类型为int,接受两个int类型参数的函数指针。
接下来,我们可以在需要使用回调函数的地方使用这个别名,比如作为另一个函数的参数。
例如:c.void performOperation(int x, int y, CallbackFunction callback) {。
int result = callback(x, y);printf("Result: %d\n", result);}。
在上面的例子中,performOperation函数接受两个int类型参数和一个CallbackFunction类型的回调函数作为参数,然后在函数内部调用这个回调函数并打印结果。
当我们实际调用performOperation函数时,我们可以传递任何符合CallbackFunction原型的函数指针作为回调函数,无需重复写函数指针的完整声明,使得代码更加简洁和易读。
总之,通过使用typedef为回调函数定义别名,我们可以使代码更加清晰易懂,提高代码的可读性和可维护性。
这种技术在C语言中经常用于回调函数的处理,尤其是在涉及到事件驱动的编程中。
c语言实现回调函数

c语言实现回调函数回调函数是一种常见的编程概念,特别在C语言中被广泛应用。
它允许我们在程序中传递一个函数作为参数,并在特定的事件发生时调用这个函数。
回调函数为我们提供了一种灵活的方式去处理异步操作、事件处理和实现代码的解耦。
在C语言中,回调函数通常通过函数指针实现。
函数指针是指向函数的指针变量,它存储了函数的地址。
通过将函数指针作为参数传递给其他函数,我们可以在需要的时候调用这个函数。
回调函数的使用场景很多,其中一个典型的应用是事件处理。
在图形用户界面(GUI)编程中,我们经常需要处理用户的各种操作,比如点击按钮、移动鼠标等。
这些操作会触发特定的事件,我们可以事先定义好相应的回调函数,并将其注册到对应的事件上。
当事件发生时,系统会自动调用相应的回调函数来处理这些事件。
以一个简单的示例来说明回调函数的使用。
假设我们有一个函数`calculate`,它接收两个整数和一个函数指针作为参数,并在内部调用这个函数来处理两个整数的运算。
代码如下所示:```#include <stdio.h>int add(int a, int b) {return a + b;}int subtract(int a, int b) {return a - b;}void calculate(int a, int b, int (*operation)(int, int)) { int result = operation(a, b);printf("The result is: %d\n", result);}int main() {int a = 5, b = 3;printf("Addition:\n");calculate(a, b, add);printf("Subtraction:\n");calculate(a, b, subtract);return 0;}```在这个示例中,我们定义了两个函数`add`和`subtract`,它们分别用于计算两个整数的加法和减法。
C语言中的回调函数(CallbackFunction)

C语⾔中的回调函数(CallbackFunction)1 定义和使⽤场合回调函数是指使⽤者⾃⼰定义⼀个函数,实现这个函数的程序内容,然后把这个函数(⼊⼝地址)作为参数传⼊别⼈(或系统)的函数中,由别⼈(或系统)的函数在运⾏时来调⽤的函数。
函数是你实现的,但由别⼈(或系统)的函数在运⾏时通过参数传递的⽅式调⽤,这就是所谓的回调函数。
简单来说,就是由别⼈的函数运⾏期间来回调你实现的函数。
这⼀设计允许了底层代码调⽤在⾼层定义的⼦程序(如图1-1所⽰)。
C语⾔中回调函数主要通过函数指针的⽅式实现。
图1-1 回调函数在软件系统的调⽤结果回调的⽤途⼗分⼴泛:[1]例如,假设有⼀个函数,其功能为读取配置⽂件并由⽂件内容设置对应的选项。
若这些选项由(hash function)所标记,则让这个函数接受⼀个回调会使得程序设计更加灵活:函数的调⽤者可以使⽤所希望的散列算法,该算法由⼀个将选项名转变为散列值的回调函数实现;因此,回调允许函数调⽤者在运⾏时调整原始函数的⾏为。
回调的另⼀种⽤途在于处理信号量。
例如⼀个程序可能在收到信号时不愿⽴即终⽌;为了保证⼀切运⾏良好,该程序可以将清理函数注册为SIGTERM信号对应的回调。
回调亦可以⽤于控制⼀个函数是否作为:Xlib允许⾃定义的谓词(NSPredicate)⽤于决定程序是否希望处理特定的事件。
#include <iostream>#include <string>using namespace std;typedef void (*FP)(char* s); //结构体表⽰函数指针void f1(char* s){cout<<s;}void f2(char* s){cout<<s;}void f3(char* s){cout<<s;}int main(int argc,char* argv[]){int funcselector=0; //定义⼀个整数⽤于控制待执⾏的函数void* a[]={f1,f2,f3}; //定义了指针数组,这⾥a是⼀个普通指针a[0]("Hello World!\n"); //编译错误,指针数组不能⽤下标的⽅式来调⽤函数FP f[]={f1,f2,f3}; //定义⼀个函数指针的数组,这⾥的f是⼀个函数指针/* Handle of funselector *///此处⽤于处理funselector,控制待执⾏的函数f[funselector]("Hello World!\n"); //正确,函数指针的数组进⾏下标操作可以进⾏函数的间接调⽤return0;}上⾯⼀个例⼦中提现了回调函数的部分作⽤。
C语言回调函数的简单运用

C语⾔回调函数的简单运⽤⽬录⼀、什么是回调函数⼆、简单的回调函数三、带参数的回调函数⼀、什么是回调函数因为在程序中,我们有很多的库函数,我们也有很多的上层函数,为了增加程序的灵活性,我们就将⼀些函数指针作为参数传递到函数⾥⾯去。
说的粗糙⼀点,就是将⼀个函数作为另⼀个函数的函数参数。
调⽤回调函数我们需要⼀个中间函数进⾏过渡。
这个中间函数的参数是⼀个函数指针。
⼆、简单的回调函数我们来写⼀个简单的例⼦,帮助我们理解:#include <stdio.h>/*回调函数1*/void callBack1(void){printf("this is callback1\n");}/*回调函数2*/void callBack2(void){printf("this is callback2\n");}/*中间函数*//*参数是⼀个函数指针*/void calc(void (*func)()){func();}int main(){calc(callBack1);printf("************\n");calc(callBack2);return 0;}分析⼀下这个简单的回调函数的运⽤。
函数从main函数开始运⾏,我们将回调函数(callBack)作为⼀个参数传递到中间函数(calc)⾥⾯,中间函数通过函数指针的⽅式来接受,通过传⼊不同的回调函数((callBack1)、(callBack2))来执⾏不同的结果。
三、带参数的回调函数上⾯的程序简单的说明了不带参数的回调函数,那么带参数的回调函数我们也可以依葫芦画瓢。
#include <stdio.h>/*回调函数1*/int callBack1(int a,int b){printf("this multiplication:\n");return a * b;}/*回调函数2*/int callBack2(int a, int b){printf("this addition:\n");return a + b;}/*中间函数*//*参数是⼀个函数指针*/int calc(int a,int b,int (*func)()){func();}int main(){int p;int q;p = calc(20,20, callBack1);printf("%d\n",p);printf("*********\n");q = calc(20, 20, callBack2);printf("%d\n", q);return 0;}在⼯作中我们的回调函数肯定不会这么简单,但是回调函数的作⽤是不去改变底层的程序,通过获得底层的数据来得到不同的数据。
转·带你用实例理解C语言回调函数

转·带你⽤实例理解C语⾔回调函数前⾔:什么是回调函数我们先来看看百度百科是如何定义回调函数的:回调函数就是⼀个通过函数指针调⽤的函数。
如果你把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被⽤来调⽤其所指向的函数时,我们就说这是回调函数。
回调函数不是由该函数的实现⽅直接调⽤,⽽是在特定的事件或条件发⽣时由另外的⼀⽅调⽤的,⽤于对该事件或条件进⾏响应。
这段话⽐较长,也⽐较绕⼝。
下⾯我通过⼀幅图来说明什么是回调:假设我们要使⽤⼀个排序函数来对数组进⾏排序,那么在主程序(Main program)中,我们先通过库,选择⼀个库排序函数(Library function)。
但排序算法有很多,有冒泡排序,选择排序,快速排序,归并排序。
同时,我们也可能需要对特殊的对象进⾏排序,⽐如特定的结构体等。
库函数会根据我们的需要选择⼀种排序算法,然后调⽤实现该算法的函数来完成排序⼯作。
这个被调⽤的排序函数就是回调函数(Callback function)。
结合这幅图和上⾯对回调函数的解释,我们可以发现,要实现回调函数,最关键的⼀点就是要将函数的指针传递给⼀个函数(上图中是库函数),然后这个函数就可以通过这个指针来调⽤回调函数了。
注意,回调函数并不是C语⾔特有的,⼏乎任何语⾔都有回调函数。
在C语⾔中,我们通过使⽤函数指针来实现回调函数。
那函数指针是什么?不着急,下⾯我们就先来看看什么是函数指针。
回调函数现在我们回到正题,来看看回调函数到底是怎样实现的。
下⾯是⼀个四则运算的简单回调函数例⼦:#include <stdio.h>#include <stdlib.h>/***************************************** 函数指针结构体***************************************/typedef struct _OP {float (*p_add)(float, float);float (*p_sub)(float, float);float (*p_mul)(float, float);float (*p_div)(float, float);} OP;/***************************************** 加减乘除函数***************************************/float ADD(float a, float b){return a + b;}float SUB(float a, float b){return a - b;}float MUL(float a, float b){return a * b;}float DIV(float a, float b){return a / b;}/***************************************** 初始化函数指针***************************************/void init_op(OP *op){op->p_add = ADD;op->p_sub = SUB;op->p_mul = &MUL;op->p_div = &DIV;}/***************************************** 库函数***************************************/float add_sub_mul_div(float a, float b, float (*op_func)(float, float)){return (*op_func)(a, b);}int main(int argc, char *argv[]){OP *op = (OP *)malloc(sizeof(OP));init_op(op);/* 直接使⽤函数指针调⽤函数 */printf("ADD = %f, SUB = %f, MUL = %f, DIV = %f\n", (op->p_add)(1.3, 2.2), (*op->p_sub)(1.3, 2.2), (op->p_mul)(1.3, 2.2), (*op->p_div)(1.3, 2.2));/* 调⽤回调函数 */printf("ADD = %f, SUB = %f, MUL = %f, DIV = %f\n",add_sub_mul_div(1.3, 2.2, ADD),add_sub_mul_div(1.3, 2.2, SUB),add_sub_mul_div(1.3, 2.2, MUL),add_sub_mul_div(1.3, 2.2, DIV));return0;}这个例⼦有点长,我⼀步步地来讲解如何使⽤回调函数。
c语言回调函数例子

c语言回调函数例子回调函数是一种极大地改变了编程模型的编程技术,它能让函数可以通过其它函数进行通信。
回调函数在 c言中也是一种重要的编程技术,它可以让程序员更加灵活、简洁的编写代码。
本文将介绍c 语言中的回调函数的定义、实现原理、实现方法以及实例讲解,以供参考。
一、定义回调函数其实就是一种从函数中回调其他函数的能力,它可以让函数可以在一个给定的时间点上被另一个函数调用。
也就是说,如果一个函数执行完毕之后会调用另一个函数,那么就可以将另一个函数的地址提供给调用者(也就是第一个函数),此时就可以将另一个函数作为回调函数。
二、实现原理回调函数的实现原理是将一个函数的地址作为参数传递给另一个函数,另一个函数根据这个参数去调用这个函数,做到函数之间的双向调用。
三、实现方法c语言中,实现回调函数以采用函数指针:在c语言中,用函数指针来进行函数调用,定义一个函数指针,指向任何一个函数,比如用函数指针pFunc指向函数func1,此时可以用(*pFunc)调用函数func1,下面是 c语言一个实现回调函数的例子:#include <stdio.h>//义一个函数指针typedef void (*pFunc)(int);//义一个函数func1void func1(int n){printf(func1, %dn);}//义一个函数func2void func2(int n, pFunc p){if (p) {p(n + 1);}}int main(){pFunc p = func1; //func1的地址赋给函数指针p func2(10, p); //时func2函数中回调func1函数return 0;}四、实例讲解下面是一个以c语言实现简单的回调函数的实例: #include <stdio.h>//义一个函数指针typedef int (*pCal) (int, int);// 两个加减乘除四个函数int add(int a, int b){return a + b;}int sub(int a, int b){return a - b;}int mul(int a, int b){return a * b;}int div(int a, int b){return a / b;}int main(){pCal p; //义一个函数指针int a=10, b=5;p = add; //函数add的地址赋给函数指针p printf(add result : %dp(a, b));p = sub; //函数sub的地址赋给函数指针p printf(sub result : %dp(a, b));p = mul; //函数mul的地址赋给函数指针p printf(mul result : %dp(a, b));p = div; //函数div的地址赋给函数指针p printf(div result : %dp(a, b));return 0;}从上面的实例可以看出,c语言可以通过函数指针来实现回调函数,将函数的地址作为参数传入,从而实现函数的双向调用。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
低层提供的 API,安装后低层不知道这个回调的名字,但它通过一个函数指针来保存这个回 调,在需要调用时,只需引用这个函数指针和相关的参数指针。 其实:回调就是该函数 写在高层,低层通过一个函数指针保存这个函数,在某个事件的触发下,低层通过该函数指 针调用高层那个函数。
四 无题 软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用、
至于钩子函数,只是回调函数的一个特例。习惯上把与 SetWindowsHookEx 函数一起使 用的回调函数称为钩子函数。也有人把利用 VirtualQueryEx 安装的函数称为钩子函数,不过 这种叫法不太流行。
也可以这样来描述:回调函数就好像是一个中断处理函数,系统在符合你设定的条件时 自动调用。为此,你需要做三件事: 1. 声明; 2. 定义; 3. 设置触发条件,就是在你的函数中把你的回调函数名称转化为地址作为一个参数,以便 于系统调用。
如今我们是活在一个 object 时代。只要与编程有关,无论何事都离不开 object。但 object 并未消除回调,反而把它发扬光大,弄得到处都是,只不过大都以事件(event)的 身份出现,镶嵌在某个结构之中,显得更正统,更容易被人接受。应用程序要使用某个构件, 总要先弄清构件的属性、方法和事件,然后给构件属性赋值,在适当的时候调用适当的构件 方法,还要给事件编写处理例程,以备构件代码来调用。何谓事件?它不过是一个指向事件 例程的地址,与回调函数地址没什么区别。
此调用机制并非完美。回调函数就是一例。函数之类本是为调用者准备的美餐,其烹制 者应对食客了如指掌,但实情并非如此。例如,写一个快速排序函数供他人调用,其中必包 含比较大小。麻烦来了:此时并不知要比较的是何类数据--整数、浮点数、字符串?于是只 好为每类数据制作一个不同的排序函数。更通行的办法是在函数参数中列一个回调函数地 址,并通知调用者:君需自己准备一个比较函数,其中包含两个指针类参数,函数要比较此 二指针所指数据之大小,并由函数返回值说明比较结果。排序函数借此调用者提供的函数来 比较大小,借指针传递参数,可以全然不管所比较的数据类型。被调用者回头调用调用者的 函数(够咬嘴的),故称其为回调(callback)。
不过,此种回调方式比传统回调函数要高明许多。首先,它把让人不太舒服的回调函数 变成一种自然而然的处理例程,使编程者顿觉气顺。再者,地址是一个危险的东西,用好了 可使程序加速,用不好处处是陷阱,程序随时都会崩溃。现代编程方式总是想法把地址隐藏 起来(隐藏比较彻底的如 VB 和 Java),其代价是降低了程序效率。事件例程(?)使编 程者无需直接操作地址,但并不会使程序减速。
回调和异步调用。同步调用是一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一 种单向调用;回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方 的接口;异步调用是一种类似消息或事件的机制,不过它的调用方向刚好相反,接口的服务 在收到某种讯息或发生某种事件时,会主动通知客户方(即调用客户方的接口)。回调和异 步调用的关系非常紧密,通常我们使用回调来实现异步消息的注册,通过异步调用来实现消 息的通知。同步调用是三者当中最简单的,而回调又常常是异步调用的基础。
Windows 系统还包含着另一种更为广泛的回调机制,即消息机制。消息本是 Windows 的基本控制手段,乍看与函数调用无关,其实是一种变相的函数调用。发送消息的目的是通 知收方运行一段预先准备好的代码,相当于调用一个函数。消息所附带的 WParam 和 LParam 相当于函数的参数,只不过比普通参数更通用一些。应用程序可以主动发送消息, 更多情况下是坐等 Windows 发送消息。一旦消息进入所属消息队列,便检感兴趣的那些, 跳转去执行相应的消息处理代码。操作系统本是为应用程序服务,由应用程序来调用。而应 用程序一旦启动,却要反过来等待操作系统的调用。这分明也是一种回调,或者说是一种广 义回调。其实,应用程序之间也可以形成这种回调。假如进程 B 收到进程 A 发来的消息, 启动了一段代码,其中又向进程 A 发送消息,这就形成了回调。这种回调比较隐蔽,弄不 好会搞成递归调用,若缺少终止条件,将会循环不已,直至把程序搞垮。若是故意编写成此 递归调用,并设好终止条件,倒是很有意思。但这种程序结构太隐蔽,除非十分必要,还是 不用为好。
声明和定义时应注意:回调函数由系统调用,所以可以认为它属于 WINDOWS 系统,不 要把它当作你的某个类的成员函数。
二,回调函数、消息和事件例程 调用(calling)机制从汇编时代起已经大量使用:准备一段现成的代码,调用者可以随时
跳转至此段代码的起始地址,执行完后再返回跳转时的后续地址。CPU 为此准备了现成的 调用指令,调用时可以压栈保护现场,调用结束后从堆栈中弹出现场地址,以便自动返回。 借堆栈保护现场真是一项绝妙的发明,它使调用者和被调者可以互不相识,于是才有了后来 的函数和构件。
三,精妙比喻: 回调函数还真有点像您随身带的 BP 机:告诉别人号码,在它有事情时 Call 您。 回调用于层间协作,上层将本层函数安装在下层,这个函数就是回调,而下层在一定条
件下触发回调,例如作为一个驱动,是一个底层,他在收到一个数据时,除了完成本层的处 理工作外,还将进行回调,将这个数据交给上层应用层来做进一步处理,这在分层的数据通 信中很普遍。其实回调和 API 非常接近,他们的共性都是跨层调用的函数。但区别是 API 是低层提供给高层的调用,一般这个函数对高层都是已知的;而回调正好相反,他是高层提 供给底层的调用,对于低层他是未知的,必须由高层进行安装,这个安装函数其实就是一个
利用消息也可以构成狭义回调。上面所举排序函数一例,可以把回调函数地址换成窗口 handle。如此,当需要比较数据大小时,不是去调用回调函数,而是借 API 函数 SendMessage 向指定窗口发送消息。收到消息方负责比较数据大小,把比较结果通过消息本身的返回值传 给消息发送方。所实现的功能与回调函数并无不同。当然,此例中改为消息纯属画蛇添脚, 反倒把程序搞得很慢。但其他情况下并非总是如此,特别是需要异步调用时,发送消息是一 种不错的选择。假如回调函数中包含文件处理之类的低速处理,调用方等不得,需要把同步 调用改为异步调用,去启动一个单独的线程,然后马上执行后续代码,其余的事让线程慢慢 去做。一个替代办法是借 API 函数 PostMessage 发送一个异步消息,然后立即执行后续代 码。这要比自己搞个线程省事许多,而且更安全。
回调函数使程序结构乱了许多。Windows API 函数集中有不少回调函数,尽管有详尽 说明,仍使初学者一头雾水。恐怕这也是无奈之举。
无论何种事物,能以树形结构单向描述毕竟让人舒服些。如果某家族中孙辈又是某祖辈的祖 辈,恐怕无人能理清其中的头绪。但数据处理之复杂往往需要构成网状结构,非简单的客户 /服务器关系能穷尽。
针类型自定义一下。 typedef void(*pcb)(char *);
回调函数可以象普通函数一样被程序调用,但是只有它被当作参数传递给被调函数时才 能称作回调函数。
被调函数的例子:
void GetCallBack(pcb callback) { /*do something*/ } 用户在调用上面的函数时,需要自己实现一个 pcb 类型的回调函数: void fCallback(char *s) { /* do something */ } 然k, GetCallBack(fCallback); 如果赋了不同的值给该参数,那么调用者将调用不同地址的函数。赋值可以发生在运行 时,这样使你能实现动态绑定。 2.2 参数传递规则 到目前为止,我们只讨论了函数指针及回调而没有去注意 ANSI C/C++的编译器规范。 许多编译器有几种调用规范。如在 Visual C++中,可以在函数类型前加_cdecl,_stdcall 或者 _pascal 来表示其调用规范(默认为_cdecl)。C++ Builder 也支持_fastcall 调用规范。调用规 范影响编译器产生的给定函数名,参数传递的顺序(从右到左或从左到右),堆栈清理责任 (调用者或者被调用者)以及参数传递机制(堆栈,CPU 寄存器等)。 将调用规范看成是函数类型的一部分是很重要的;不能用不兼容的调用规范将地址赋值 给函数指针。例如: // 被调用函数是以 int 为参数,以 int 为返回值 __stdcall int callee(int); // 调用函数以函数指针为参数 void caller( __cdecl int(*ptr)(int)); // 在 p 中企图存储被调用函数地址的非法操作 __cdecl int(*p)(int) = callee; // 出错 指针 p 和 callee()的类型不兼容,因为它们有不同的调用规范。因此不能将被调用者的 地址赋值给指针 p,尽管两者有相同的返回值和参数列 2.3 应用举例 C 语言的标准库函数中很多地方就采用了回调函数来让用户定制处理过程。如常用的快 速排序函数、二分搜索函数等。 快速排序函数原型:
回调函数
一,回调函数定义 我们经常在 C++设计时通过使用回调函数可以使有些应用(如定时器事件回调处理、用
回调函数记录某操作进度等)变得非常方便和符合逻辑,那么它的内在机制如何呢,怎么定 义呢?它和其它函数(比如钩子函数)有何不同呢?
使用回调函数实际上就是在调用某个函数(通常是 API 函数)时,将自己的一个函数 (这个函数为回调函数)的地址作为参数传递给那个函数。而那个函数在需要的时候,利用 传递的地址调用回调函数,这时你可以利用这个机会在回调函数中处理消息或完成一定的操 作。至于如何定义回调函数,跟具体使用的 API 函数有关,一般在帮助中有说明回调函数 的参数和返回值等。C++中一般要求在回调函数前加 CALLBACK(相当于 FAR PASCAL), 这主要是说明该函数的调用方式。
在面向对象的语言中,回调则是通过接口或抽象类来实现的,我们把实现这种接口的类 成为回调类,回调类的对象成为回调对象。对于象 C++或 Object Pascal 这些兼容了过程特性 的对象语言,不仅提供了回调对象、回调方法等特性,也能兼容过程语言的回调函数机制。