对于许多异步事件的处理,都是通过回调函数来实现的。例如:网络中域名的解析INetMgr_GetHostByName(); Socket通信中连接服务器ISOCKET_Connect();
Socket通信中发送数据ISOCKET_Writeable();Socket通信中接收数据ISOCKET_Readable(); 定时器Timer等等。
在异步事件的处理,首先将异步事件发生时需要执行的代码编写成一个函数,并将该函数注册成为回调函数,这样当该异步事件发生时,系统会自动调用事先注册
好的回调函数。回调函数的注册实际上就是将回调函数的信息填写到一个用于注册回调函数的结构体变量中。 各种不同异步事件的回调函数注册方法有所不同。
各种不同异步事件的回调函数注册方法有所不同。一般来说,回调函数的注册用CALLBACK_Init(),回调函数的取消用CALLBACK_Cancel()。有些接口有自己专门
的函数来注册回调函数。Socket连接在ISOCKET_Connect()中注册回调函数。Socket通信在ISOCKET_Writeable() /ISOCKET_ Readable() 中注册回调函数
回调机制-用C语言实现回调函数的简单例子#include <stdio.h>
typedef void(*CBTest)(void *p);
//==用于注册回调函数的结构体
typedef struct _ cbDemo CBDemo;
struct _cbDemo{
CBTest cb; //指向回调函数的指针
void * cbParam; //指向参数的指针
int i;
};
//==本函数用于注册回调函数==========
// 参数:pDemo:用于注册回调函数的结构体
// test:要注册的回调函数
// p:回调函数被调用时使用的参数
//=========================
void RegisterCallback(CBDemo *pDemo,CBTest, void *p)
{
pDemo ->cb = test; //结构体的cb指向回调函数
pDemo ->cbParam = p; //结构体的cbParam指向参数
}
数据类型,包含i、j两个整形成员变量
typedef struct _Data Data;
struct _Data
{
int i;
int j;
};
//本例中要作为回调函数的两个函数:Test()和Test2()
void Test(void *p)
{
((Data*)p)->i ++;
((Data*)p)->j++;
}
void Test2(void *p)
{
((CBDemo*)p)->I = 10;
}
void main() //主函数
{
CBDemo demo; //用于注册回调函数的结构体变量demo
Data data;
demo.i = 1;
data.i = 10;
data.j = 11;
RegisterCallback( &demo, Test,&data); //将Test()注册为回调函数
printf( “%d, %d \n”, data.i, data.j);
demo.cb(demo.cbParam); //通过demo.cb(demo.cbParam)调用回调函数
printf(“ %d, %d\n”,data.i , data.j);
RegisterCallback( &demo, Test2, &demo); //将Test2()注册为回调函数
printf(“%d\n”,demo.i);
demo.cb(demo.cbParam);
printf(“ %d\n”, demo.i);
}
本例中,分别将Test()和Test2()注册为回调函数,代码如下:
注册回调函数
RegisterCallback( &demo, Test, &data);
该语句将Test()注册为回调函数,并且指定将来调用回调函数Test()时,以data作为Test()的参数;注册时将Test()的地址和data的地址
填入结构体变量demo中
RegisterCallback( &demo, Test2, &demo); 该语句将Test2()注册为回调函数,并且指定将来调用回调函数Test2()时,以demo作为Test2()的参数;注册时将Test2()的地址和demo
的地址填入结构体变量demo中
调用回调函数 调用回调函数时,都是从结构体变量demo取出回调函数的地址及参数来执行回调函数的,因此,无论注册的回调函数和参数是什么,执行回调函
数的方式是一样的: demo.cb(demo.cbParam);