NS3中回调
来源:互联网 发布:鞍钢职工居家工资算法 编辑:程序博客网 时间:2024/05/16 08:59
在了解NS3回调机制前先学习C/C++中的函数指针
函数指针指的是指向函数的指针(* ptr)
声明形式:
返回类型 (*函数指针名)(函数形參表)(=初始值)
C语言中的函数指针:
int (*p)(int a)=0;int function(int a){a=0;}a=function;// or 加上地址符&int res=a(12)//类似 function(12)
typedef 返回类型(*函数指针类型名)(函参列表)
如
typedef int(*callback)(int a)将函数指针名替换成了类型名即声明了一个新类型:
using namespace std; typedef void(*FUN)(int,int); //定义函数指针类型 void min(int a,int b); void max(int a,int b); void min(int a,int b) { int minvalue=a<b?a:b; std::cout<<"min value is "<<minvalue<<"\n"; } void max(int a,int b) { int maxvalue=a>b?a:b; std::cout<<"Max value is "<<maxvalue<<"\n"; } //void test(void (*f)(int a,int b),int a,int b) void test(FUN f,int a,int b) { f(a,b); } int main() { FUN pFun=NULL; //定义函数指针变量pFun pFun=&min; test(min,1,2); test(&max,1,2); return 0; }
C++语言中的函数指针:
C++与C语言函数指针区别是指向调用类成员函数class A{public: int methord(int a);};int (A::*p)(int a)=0;//要加类名p=&A::methord;
回调callback:
当程序跑起来时,一般情况下,应用程序(application program)会时常通过API调用call库里所预先备好的函数。但是有些库函数(library function)却要求应用先传给它一个函数,好在合适的时候调用call传给它的应用层函数,以完成目标任务。这个被传入的、后又被调用的函数就称为回调函数(callback function)。
打个比方,有一家旅馆提供叫醒服务,但是要求旅客自己决定叫醒的方法。可以是打客房电话,也可以是派服务员去敲门,睡得死怕耽误事的,还可以要求往自己头上浇盆水。这里,“叫醒”这个行为是旅馆提供的,相当于库函数,但是叫醒的方式是由旅客决定并告诉旅馆的,也就是回调函数。而旅客告诉旅馆怎么叫醒自己的动作,也就是把回调函数传入库函数的动作,称为登记回调函数(to register a callback function)。如下图所示(图片来源:维基百科):
应用层函数A--->call 底层库函数B------>call (back)应用层函数C
可以看到,回调函数通常和应用处于同一抽象层(因为传入什么样的回调函数是在应用级别决定的)。而回调就成了一个高层调用底层,底层再回过头来调用高层的过程。也是其callbak得名如此的原因。
回调机制提供了非常大的灵活性,图中的库函数改称为中间函数了,这是因为回调并不仅仅用在应用和库之间。任何时候,只要想获得类似于上面情况的灵活性,都可以利用回调。跟直接调用call不同,在回调中,我们利用某种方式,把回调函数像参数一样传入中间函数(实质就是函数指针)。可以这么理解,在传入一个回调函数之前,中间函数是不完整的。换句话说,程序可以在运行时,通过登记不同的回调函数,来决定、改变中间函数的行为。这就比简单的函数调用要灵活太多,举例:
#include<iostream> using namespace std; typedef int (*geteven)(int a);//声明函数指针并声明为新类新geteven int get2res(int a) {return 2*a;} int get4res(int a) {return 4*a;} int getOdd(int a,geteven fun){ return 1+fun(a); } int main(){ int a=1; int res; res=getOdd(a,get2res);//2*k+1 cout<<res<<" "; res=getOdd(a,get4res);//4*k+1 cout<<res;return 0;}起始函数即中间函数调用者为main函数,中间函数为getOdd函数,回调函数有两种get2res和get4res,如上所说,中间函数getOdd函数需要起始函数传入参数函数指针才是一个完整函数,,程序可以在运行时,通过登记不同的回调函数(get2res和get4res),最后中间函数完成的功能不一样。
总而言之:调用者A提供的函数来完成功能,借指针传递参数给被调用者B,可以全然不管所比较的数据类型。被调用者B回头调用调用者的函数C,故称其为callback
NS3回调callback:
ns3主要提供Callback类API接口来为用户提供服务 ,分为两步骤:
1用给定的签名声明回调的类型
2回调实例化
Callback 与 MakeCallback是成对出现的,其类型如下
1. Callback其实类似于“指向函数的指针"Callback模板类: Callback< R, T1, T2, T3, T4, T5, T6, T7, T8, T9 >其中 R为Callback的返回类型,必选T1...T9是Callback的实参,可选,默认值为empty
2. MakeCallback
template<typename T , typename OBJ , typename R , typename T1 >
Callback< R, T1 > ns3::MakeCallback (R(T::*)(T1) mem_ptr, OBJ objPtr)
模板类MakeCallback的返回值为Callback类型
mem_ptr: class method member pointer
objPtr: class instance
返回值: a wrapper Callback Build Callbacks for class method members which takes one argument and potentially return a value.
针对静态函数
static doubleCbOne(double a,double b){std::out<<"a="<<a<<"b="<<b<<std::endl;return a; }int main(int argc,char *argv[]){//返回类型 double//第一个参数 double//第二个参数 doubleCallback<double,double,double> one; //回掉实例化,第一个参数是返回值,第二和第三是参数one = MakeCallback(&CbOne);//讲回调one,通过API MakeCallback()与相应的函数进行匹配NS_ASSERT(!one.IsNull());//检查一下回调one是否为空double retone;retone = one(10.0,20.2);//此时one的功能和CbOne的功能是一样的}
针对类成员函数
class Mycb{public:int CbTwo(double a){std::out<<"a="<<a<<std::endl;return -5;}} //返回类型 int//参数 doubleCallback<int,double> two;Mycb cb;//创建一个回调,并让他指向Mycb::CbTwotwo = MakeCallback(&Mycb::CbTwo,&cb);//与静态函数差别多一个参数,即实例化的cb的地址//调用的时候也就是调用cb的CbTwo函数NS_ASSERT(!two.IsNull());//判断回调two不为空int retTwo;retTwo = two(10.0);NS_ASSERT(retTwo == -5);return 0;}针对Null的回调
Two = MakeNullCallback<int,double>(); //构建空的回调int retTwo = Two(10.2);
- NS3中回调
- NS3
- NS3
- NS3
- NS3
- NS3
- NS3
- NS3
- NS3
- ns3 安装
- NS3官方网站
- NS3 Callbacks
- NS3入门
- ns3笔记
- ns3 学习心得
- eclipse+NS3
- ns3-3
- ns3-4
- Angular自定义指令实现一般性的表单验证
- linux之find命令详解
- 我的16秋招感受
- Linux音频驱动-PCM设备
- 自然语言词性示例
- NS3中回调
- CIPAddressCtrl::GetAddress使用心得
- iOS 学习笔记 --- 定时器NSTimer、CADisplayLink、GCD
- Hibernate 离线查询参数
- 常用Git命令整理
- 设计模式之观察者模式
- 素数环
- Swift retrieved by calling -dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:
- 零基础学习 Hadoop 如何下手