【回调函数】
函数指针是一个指向特定函数的指针。
函数的类型由其参数及返回类型共同决定,与函数具体名称无关。
示例:
int fun1(int param1, long param2, float param3); //普通函数定义
该函数的类型为int(int, long, float),
该类型的函数指针可以定义为如下:
int (*pfun1)(int, long, float);
要声明一个函数指针,只需要将普通函数名变为指针,同时用()将指针名扩起来即可;
()是必不可少的。int pfun1(int, long, float)表示的是一个返回值为int的普通函数。
【示例1】
typedef struct test_dbg{
boolean state;
byte debug_type;
byte pad[6]; /*align to 64-bit*/
boolean (*cmp_key)(void *entry, struct test_dbg *dbg);
boolean (*filter_match)(struct test_dbg *dbg, void *cookie);
void (*print_key)(void *entry, char *buffer);
void (*des_struct)(struct test_dbg *dbg);
byte key[0];
}T_TEST_DBG;
改造后:
typedef boolean (*test_dbgItemKeyCmpFuncPtr) (void* item, struct test_dbg* dbg);
typedef void (*test_dbgItemKeyPrintFuncPtr) (void* item, char* buffer);
typedef void (*test_dbgItemKeyFreeFuncPtr) (struct test_dbg* dbg);
typedef struct test_dbg{
boolean state;
byte itemKeyType;
byte pad[6];
test_dbgItemKeyCmpFuncPtr pItemKeyCmpCall;
test_dbgItemKeyPrintFuncPtr pItemKeyPrintCall;
test_dbgItemKeyFreeFuncPtr pItemKeyFreeCall;
byte key[0];
}T_TEST_DBG;
int test_debug_reg_callback()
{
T_TEST_DBG tDebug;
memset(&tDebug, 0, sizeof(T_TEST_DBG));
tDebug.pItemKeyCmpCall = test_key_cmp_cb;
tDebug.pItemKeyPrintCall = test_key_print_cb;
tDebug.pItemKeyFreeCall = test_key_free_cb;
return SUCCESS;
}
[注]:挂接的回调函数的返回值类型和入参列表要与函数指针类型保持一致
boolean test_key_cmp_cb(void* item, struct test_dbg* dbg)
{
......
return TRUE;
}
[注]:在其他模块预留的函数指针处,挂载本模块对应功能的函数即可。
什么时候调用,给函数指针传入什么参数,都由预留函数指针的模块来实现。
【示例2】
typedef int (*CLIENT_RCV_MSG_NO_ACK_FUNC)(void *pArg, byte *pData, int len);
typedef int (*CLIENT_RCV_MSG_NEED_ACK_FUNC)(void *pArg, byte *pData,int len,byte *pAckBuf,int ackBufLen,int *pOutAckLen);
typedef struct tagRCV_MSG_FUNC_INFO
{
CLIENT_RCV_MSG_NO_ACK_FUNC noNeedAckFunc;
void *pNoNeedAckFuncArg;
CLIENT_RCV_MSG_NEED_ACK_FUNC needAckFunc;
void *pNeedAckFuncArg;
}RCV_MSG_FUNC_INFO;
int client_rcv_msg_no_ack(CLIENT_HDL* pHdl, MSG* pMsg, int wMsgLen)
{
CLIENT_RCV_MSG_NO_ACK_FUNC func = NULL;
......
func = pSvrNode->funcInfo.noNeedAckFunc;//挂回调,获取函数指针,其函数指针类型为CLIENT_RCV_MSG_NO_ACK_FUNC
if (NULL != func)
{
//填写参数,调用函数指针指向的函数
ret = func(pSvrNode->funcInfo.pNoNeedAckFuncArg,
pData,
pMsg->msgLen);
}
......
}