回调总结

在网上也看了不少相关的资料,总觉得少了些什么,于是自己动手,看能不能结合自己的经验,通俗易懂地描绘下。不对和不足之处请大家共同纠正。

一、函数调用类型

    假定有2个模块,A和B。

1、同步调用

这个最基础了,就是a.func直接调用b.func。没什么好说的。

2、同步回调(采纳很多网友的说法,主要是为了有别于异步回调)

此类型个人感觉多用于实现"多样(态)化",比如网上常见的f_cmp。

此流程为A->B->A,最终的"多样(态)化"实现都是在A模块。

A模块给函数指针pfunc赋值(没有用注册/之类的,区别见异步调用),B模块使用即可。

可以从一般的形参角度来看此pfunc。

3、异步回调

此类型是很多网友都没有说通透的。我来试一试。

此流程A<-B。怎么理解呢,这里就要涉及注册/关联。在A模块中把a.func和B模块中的b.func关联起来。

A中

{

B.attach(pafunc,...);    //pafunc为指向a.func的函数指针

......

B.disattach(,,...);

}

B中

{

B.attach(pafunc,...)

{

b.func = a.func;

}

b.fun()

{

}

}

这个就是最通用的dispatch机制。假如A为GUI中的Pages,B为GUI中的Mouse。

Mouse获取Message后dispatch给Pages。

先以产品级的GUI来描述。

//GUI同步回调例子

/*按键处理函数*/

typedef int (CGui::*KeyHandlerFuncPtr)(key_enum key, void *para);

KeyHandlerFuncPtr pKeyHander = NULL;

int CGui::HandleKey(key_enum  key, void *para)

{

if(pKeyHander)

{

return (this->*pKeyHander)(key, para);

}

return -1;

}

//在线程中获取key

void CGui::GuiThreadBody()

{

......

key_enum keyval;

if(keyval!= KVT_INVALID)

{

HandleKey(keyval, NULL);

}

......

}

//初始化第一个pKeyHander,也就是开机后第一个界面的handler

pKeyHander  = NULL;

void CGui::InitGui()

{

......

pKeyHander = &CGui::Page0Handler;

......

}

//后续的handler在Page0Handler()中赋值

int CGui:: Page0Handler(key_enum  key, void *para)

{

......

if(page1)

{

pKeyHander = &CGui::Page1Handler;

}

......

}

//在page1中也可以返回page0

int CGui:: Page1Handler(key_enum  key, void *para)

{

......

if(page0)

{

pKeyHander = &CGui::Page0Handler;

}

......

}

//GUI异步回调例子

void CMOUS::MouseThreadBody()

{

SignalKey(key,pos,void*);

}

int CMOUS::Attach(pfunc)

{

SignalKey = Page:InputKey;

}

int Page:InputKey()

{}

int Page:Page0()

{

g_Mouse.attach(pInputKey);      //attach

}

大家可以参考下SDL的Audio的回调,这个也是异步的。

App中

{

static int stream_component_open(VideoState *is, int stream_index)

{

......

SDL_AudioSpec wanted_spec;

wanted_spec.callback = sdl_audio_callback;     //attach

if (SDL_OpenAudio(&wanted_spec, &spec) < 0)

{}

......

}

void sdl_audio_callback(void *opaque, Uint8 *stream, int len)

{

}

}

SDL中

{

在code中跟踪SDL_AudioSpec,可以看到App. sdl_audio_callback()中的*stream是由SDL传给APP中的

}

一个小小的trick,当你在你的app中没有找到某函数的显示调用(但确实调用了),而且其形参也"来路不明"

时,你就要怀疑此函数是否是异步调用了。

最后一句话,回调讲完了,C++"委托"还会远么。

来自为知笔记(Wiz)

时间: 2024-10-21 16:04:20

回调总结的相关文章

谈谈-Android中的接口回调技术

Android中的接口回调技术有很多应用的场景,最常见的:Activity(人机交互的端口)的UI界面中定义了Button,点击该Button时,执行某个逻辑. 下面参见上述执行的模型,讲述James对Android接口回调技术的理解(结合前人的知识和自己的实践). 使用一个比喻很形象地说明:客户端有个疑问打电话请教服务端,但服务端无法现场给出解答,相互之间约定:服务端一旦有答案,使用电话的方式反馈给客户端. 以上有三个主体:客户端.服务端和接口(方式). 接口回调的原理框图说明: Demo界面

android使用友盟实现第三方登录、分享以及微信回调无反应问题解决办法

        Leaning_wk每一次的进步都会拉近与成功的距离! 帐号设置退出   关闭 qq_15855289的博客 目录视图 摘要视图 订阅 异步赠书:Kotlin领衔10本好书      免费直播:AI时代,机器学习如何入门?      程序员8月书讯      每周荐书:Java Web.Python极客编程(评论送书) android使用友盟实现第三方登录.分享以及微信回调无反应问题解决办法 标签: android友盟第三方登录分享微信登录回调问题 2017-02-10 16:2

php7微信支付回调失败

升级完PHP7 发现微信支付回调失败.原来是 $GLOBALS['HTTP_RAW_POST_DATA'];没有定义的问题.php7 移除了这个全局变量. 修改如下: //获取通知的数据 $xml = $GLOBALS['HTTP_RAW_POST_DATA'];//这里在php7下不能获取数据,使用 php://input 代替 if(!$xml){ $xml = file_get_contents("php://input"); }

Android实现组件之间同步的回调通信

Android开发中,有时会遇到组件之间相互通信回调的问题.一般都是通过Android提供的ResultReceiver来实现(ResultReceiver的使用方法很简单,这里就不多提了). 但之前在工作中,遇到了一个组件间回调的问题,ResultReceiver无法满足需求.简单描述一下问题:service中打开了一个activity,activity需要将一个变量值回调给service,而且这个回调必须是同步的.也就是说activity在确认service接收到了这个变量值后,才能继续向下

嵌入式&amp;iOS:回调函数(C)与block(OC)传 参/函数 对比

C的回调函数: callBack.h 1).声明一个doSomeThingCount函数,参数为一个(无返回值,1个int参数的)函数. void DSTCount(void(*CallBack)(int data_i32)); callBack.c 1).在doSomeThingCount函数,对运行次数自增,并调用参数--函数. void DSTCount(void(*CallBack)(int data_i32)) { static int numb = 0; numb++; (*Call

回调函数的本质,就是把函数当作参数(首先要定义函数类型)

//把一个方法当作另一个方法的参数, 就是回调方法, 大家习惯称作回调函数 type   TFunType = function(i: Integer): Integer; {声明一个方法类型} function MyFun(i: Integer): Integer;        {建立类型兼容的函数} begin   Result := i*2; end; {把函数当作参数, 再定义一个函数} function MyTest(x: Integer; F: TFunType): Integer

js异步回调

简单理解:js是单线程的,Ajax请求远程数据.IO等会很耗时,引起堵塞可能会引起反应时间太长页面失去反应. 回调:A函数作为一个参数传给B函数,执行完B后再执行A: 同步回调: 1 function A{ 2 alert('1'); 3 } 4 function B(nn){ 5 alert('2'); 6 nn(); 7 } 8 B(A); 原文网址:http://www.html5cn.org/article-9915-1.html?utm_medium=hao.caibaojian.co

Java回调机制

以前不理解什么叫回调,天天听人家说加一个回调方法啥的,心里想我草,什么叫回调方法啊?然后自己就在网上找啊找啊找,找了很多也不是很明白,现在知道了,所谓回调:就是A类中调用B类中的某个方法C,然后B类中反过来调用A类中的方法D,D这个方法就叫回调方法,这样子说你是不是有点晕晕的,其实我刚开始也是这样不理解,看了人家说比较经典的回调方式: Class A实现接口CallBack callback——背景1 class A中包含一个class B的引用b ——背景2 class B有一个参数为call

MFC 定时器 SetTimer 如何使用回调函数

创建工程名TestCallBack 自定义回调函数   定义为全局函数 在TestCallBackDlg.h文件开头定义 #pragma once void CALLBACK EXPORT TimerProc(HWND hWnd,UINT nMsg,UINT nTimerid,DWORD dwTime); 在TestCallBackDlg.cpp文件末尾实现函数 void CALLBACK EXPORT TimerProc(HWND hwnd,UINT message,UINT iTimerID

回调在python中

回调 函数作为参数 函数执行=> 到一个参数函数时=> 调用另一个函数=> 回到主函数 #!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'teng' def test(callback):     print 'test func begin'     callback() def test1(callback):     print 'test1 func begin'     for func in callback