C++回调函数

回调函数笔记-暨海康相机硬触发调试经历

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。

C语言使用回调函数原因:软件分层:单向依赖-回调函数就是将双向依赖转为单向依赖的工具

常见的回调函数:多线程:函数创建是给其他函数调用就叫回调函数,此处cb函数做为pthred_create中的一个参数。

#include<pthread.h>  
#include<unistd.h>  
#include<stdio.h>  
void *cb(void *arg)  
{  
   //pthread_self()获取本线程ID
   print("call back running,%u\n",pthread_self());  
   return NULL;  
}  
int main (void)  
{  
  //创建了两个线程,每个线程执行函数都是cb
  pthred_t tid;  
  pthred_create(&tid,NULL,cb,NULL); 
  pthred_t tid2;  
  pthred_create(&tid2,NULL,cb,NULL); 
  pthred_join(tid,NULL); 
  pthred_join(tid2,NULL); 
}  

                       

为什么可以使用回调函数-函数指针

#include <stdio.h>
void fun1(void)
{
  print("我是fun1\n");
}
 
void fun2(void)
{
  print("我是fun2\n");
}

int main(void)
{
  void(*p)(void); //函数指针,只能指向无参,无返回值的函数
  void(*p1)(int,int);//另一个函数指针,能够指向两个整形参数
  //无返回值的函数
  
  char(*p2)(int) //函数指针,指向有一个整形参数,一个返回值的函数
  void *(*p3)(int *); 
  //只能指向这样的函数
  //void *fun(int *a);

  //函数指针赋值必须函数头相同
 //fun1()函数赋值给函数只能给void(*p)(void);
  p=fun1; //让p这个指针指向fun1整个函数
  //函数其实就是一个代码块,这个代码块执行到最后会返回
  p(); //函数指针的运行(简写的方法),实际就是他指向的函数对象的运行
  (*p)(); //原始的运行方法,表示通过*找到所指向的对象,然后让他运行  
  p=fun2;
  p();//改变p的指向  
}

为什么不直接调用函数,而是通过函数指针间接调用函数

以上代码唯一好处是p可以随意更改对象

回调函数

回调函数是一种在定义的模块不运行,交给另一个模块运行的函数

//run.cpp
#include<unistd.h>
//无限运行函数,每秒自增1,可以算是秒的函数
void run(void) //一个死循环
{
 int c=0;
 while(1)
   {
    c++;
    sleep(1);
   } 
}
//main.cpp
int main(void)
{ 
  run();
}


//希望在run的循环里,每秒运行一个函数,但是这个函数由main()来指定(函数放在main里)
//run.cpp
#include<unistd.h>
void(*step)(void); //定义一个函数指针
//无限运行函数,每秒自增1,可以算是秒的函数
void run(void) //一个死循环
{
 int c=0;
 while(1)
   {
    if(step!=NULL) //没有赋值之前不能运行
       {step();}  //在循环里运行
    c++;
    sleep(1);
   } 
}
//main.cpp
int main(void)
{ 
  run();
}
//现在只有main.cpp依赖run.cpp而run.cpp不依赖于main.cpp


//双向依赖
//run.cpp
#include<unistd.h>
void(*step)(void);
void run(void) 
{
 int c=0;
 while(1)
   {
    if(step!=NULL) 
       step();  
    c++;
    sleep(1);
   } 
}

//main.cpp
//extern是计算机语言中的一个关键字,可置于变量或者函数前,以表示变量或者函数的定义在别的文件中。
//提示编译器遇到此变量或函数时,在其它模块中寻找其定义,另外,extern也可用来进行链接指定。
//先声明,在使用
extern void(*step)(void);
void mystep_cb(void)
{
printf("记秒倒时、n")
}

int main(void)
{ 
  step*mystep_cb;
  run();
}

回调函数的应用:尤其是在调用的对象是个黑盒子,通常是别的公司打包好的某个库,编程时要改变库里的某些默认行为,这时用回调函数是最好的。

同样的场景适用于windows操作系统底层行为。

run.cpp

void(*step)(int) =NULL;
void run(void) 
{
 int ct=0;
 while(1)
   {
    if(step!=NULL) 
       step(ct);  
    ct++;
    sleep(1);
   } 
}

void cb_install(void (*p)(int))
{
  step=p;
}

main.cpp

//main.cpp

void(*step)(void)(*p)(int));
void mystep_cb(int i)
{
printf("记秒倒时,i=%d\n",i);
}

int main(void)
{ 
  cb_install(mystep_cb);
  run();
}

回调函数的适用条件

1.模块之间相互独立,存在相互之间调用

2.两个模块处在不同的层次,为了确保单向依赖(单向调用),通常在下层设置函数指针,然后在上层设置回调函数。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值