函数调用很好理解,即使刚学没多久的朋友也知道函数调用是怎么实现的,即调用一个已经封装好的函数,实现某个特定的功能。
把一个或者多个功能通过函数的方式封装起来,对外只提供一个简单的函数接口,然后在其他地方调用即可
函数调用方式函数调用难道还能怎么调用?不就封装好直接调用吗???
函数调用方式分为两种:直接调用和间接调用
直接调用
直接调用就是我们平常使用的方式,下面的方式就属于直接调用了。
intSumFun(inta,intb)
{
returna+b;
}
intmain()
{
//直接调用定义好的函数
intsum=SumFun(5,6);
printf("sum=%d",sum);
return0;
}
间接调用
间接调用在初学时很难使用到,这是通过函数指针的方式实现的。
函数指针本质是一个指针变量,是一个指向函数的指针(函数本身也是有地址的,指向的是函数入口);
而指针函数本质是一个函数,其返回值为指针。
函数指针的用法如下:
typedefint(*FunctionCB)(int,int);
intSumFun(inta,intb)
{
returna+b;
}
intmain()
{
//将定义好的函数赋值给函数指针
FunctionCBpfnSum=SumFun;
//通过函数指针间接调用
intsum=pfnSum(5,6);
printf("sum=%d",sum);
return0;
}
什么场景使用
函数指针在软件架构分层设计中十分重要,因为分层设计中有一个设计原则,那就是下层函数不能直接调用上层函数,那么可以通过函数指针的方式实现;一般称上层通过函数指针赋值给下层的函数为回调函数。
什么情况会存在需要下层程序需要调用上层程序的呢?
比如串口数据接收,虽然可以通过查询的方式接收,但是远不及通过串口中断的方式接收及时,当接收完成时,需要立即通知上层读取数据进行处理,而不是等待上层程序查询读取。
如何实现呢?
比如硬件抽象层/驱动层中的串口模块实现函数
/*************UART.c文件****************/
staticUartRecvCBsg_pfnUartRecv;
//设置数据帧接收处理回调函数
voidUART_SetRecvCallback(UartRecvCBpfnUartRecv)
{
sg_pfnUartRecv=pfnUartRecv;
}
voidUART_Task(void)
{
if(RecvEnd)
{
//数据一帧接收完成立即调用
if(sg_pfnUartRecv!=NULL)
{
sg_pfnUartRecv(UartRecvBuf,UartRecvLength);
}
}
}
/*************UART.h文件****************/
typedefvoid(*UartRecvCB)(constchar*,int);
externvoidUART_SetRecvCallback(UartRecvCBpfnUartRecv);
externvoidUART_Task(void);
应用层代码中实现回调函数,并调用下层函数。
//回调函数:串口数据处理
voidOnUartRecvProcess(constchar*pBuf,intlength)
{
//处理串口数据
printf("Recv:%s",pBuf);
}
intmain()
{
UART_SetRecvCallback(OnUartRecvProcess);
while(1)
{
if(TimeFlag)
{
UART_Task();
}
}
}
上述示例中通过函数指针的方式间接调用了应用层的函数,而且并不违背分层设计原则。
如果看代码不能立即理解的话,可以尝试通过下图理解:
-
嵌入式
+关注
关注
5068文章
19013浏览量
303119 -
接口
+关注
关注
33文章
8494浏览量
150815
原文标题:函数调用在嵌入式架构设计中的应用
文章出处:【微信号:strongerHuang,微信公众号:strongerHuang】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论