1. 函数指针
函数指针就是指向函数的指针变量。
- 用法一:定义函数指针,给函数指针赋值,然后调用,类似指针
#include <stdio.h>
#include <stdlib.h>
/* 定义全局函数指针pfun,返回类型void,参数int data
void (*pfun)(int data);
void myfun(int data)
{
printf("get data:%d\n",data);
}
int main(int argc,char *argv[])
{
pfun = myfun; //函数指针赋值,指向myfun函数
(*pfun)(100); //调用函数
return 0;
}
- 用法二:typedef 原变量类型 别名
#include <stdio.h>
#include <stdlib.h>
typedef void (*pfun)(int data);
/*typedef的功能是定义新的类型。第一句就是定义了一种pfun的类型,并定义这种类型为指向某种函数的指针,这种函数以一个int为参数并返回void类型。*/
void myfun(int data)
{
printf("get data:%d\n",data);
}
int main(int argc,char *argv[])
{
pfun p= myfun; //函数指针指向执行函数的地址
p(100); //和上一种用法的区别在于这里不用取地址符
return 0;
}
- 用法三:用结构体函数指针
#include <stdio.h>
#include <stdlib.h>
typedef struct gfun{
void (*pfun)(int);
}gfun;
void myfun(int data)
{
printf("get data:%d\n",data);
}
int main(int argc,char *argv[])
{
gfun gcode={
.pfun = myfun, //将函数指针指向要调用函数的地址
};
gcode.pfun(100);
return 0;
}
2. 函数指针应用
背景:某企业平台,需要同时开发多款产品,产品之间不交互,但架构相似
平台代码:
#include<iostream>
#include"lib_main.h"
using namespace std;
/* 定义全局函数指针结构体变量*/
funcs g_hook_func;
void hook_func_init()
{
g_hook_func.func1=NULL;
g_hook_func.func2=NULL;
}
int main()
{
char name[10];
int result = 0 ;
memset(name,0,sizeof(name));
hook_func_init();
hook_func();//钩子挂接函数,多线程情况应该在产品侧挂接
if(g_hook_func.func1 != NULL)
{
if(0 == g_hook_func.func1(name))
{
cout<<"err";
return -1;
}
}
if(g_hook_func.func2 != NULL)
{
result = g_hook_func.func2(1,2);
}
cout<<name<<" "<<result<<endl;
return 0;
}
平台头文件:
#ifndef _LIB_MAIN_H_
#define _LIB_MAIN_H_
/* 定义结构体函数指针 */
typedef struct func
{
int (*func1)(char * str);
int (*func2)(int a,int b);
}funcs;
extern void hook_func(); //函数指针赋值函数,在产品实现
#endif
产品1代码:
/* 先将结构体定义包含进来 */
#include"lib_main.h"
#include"wlan.h"
#include<iostream>
using namespace std;
static int getname(char * str)
{
if(NULL == str)
{
return 0;
}
//入参大小由调用者保证不越界
str[0]='w';
str[1]='l';
str[2]='a';
str[3]='n';
str[4]='\0';
return 1;
}
static int add(int a, int b)
{
return (a+b+3);
}
void hook_func()
{
g_hook_func.func1 = getname;
g_hook_func.func2 = add;
}
产品1头文件
#ifndef _WLAN_H_
#define _WLAN_H_
extern funcs g_hook_func;
#endif
其他产品和产品1一样,只是函数实现不一样,不需要的函数指针不赋值或赋值为NULL
3. 回调函数
通过函数指针调用的函数。函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数.
举例:在test中定义注册函数和函数指针类型,在main.c中将函数地址注册给test,test在满足某种条件下会调用这个注册的回调函数
main.c
#include "test.h"
#include <stdio.h>
#include <stdlib.h>
int myfun(int data)
{
printf("get data %d\n",data);
return data*2;
}
int main(int argc, char *argv[])
{
int iRet;
/* 调用rt_data函数注册回调函数myfun */
iRet = rt_data(100,myfun);
printf("return data %d\n",iRet);
return 0;
}
test.c
#include "test.h"
int rt_data(int data, pfun fun)
{
/* 一般有某种条件满足或事件发生时才会回调 */
return (fun(data));
}
test.h
#ifndef _TEST_H
#define _TEST_H
typedef int (*pfun)(int); //定义函数指针类型
int rt_data(int data,pfun fun);
#endif