NS3-回调

扫码查看

title: 6、NS中的回调
tags: NS-3,C++,Simulation,Callback,Function Pointer
slug: storywriter/upgrade_log
grammar_mindmap: true
renderNumberedHeading: true
grammar_code: true
grammar_decorate: true
grammar_mathjax: true


NS3中的回调(callback.cc)

NS3中的回调
  普通函数的回调|(FunctorCallbackImpl)
    BoundFunctorCallbackImpl
  方法的回调|(MemPtrCallbackImpl)
   BoundMemPtrCallbackImpl
  具体的实现
        MakeCallback()
        MakeBoundCallback()

普通函数的回调(FunctorCallbackImpl)

  • 回调的类型:Callback<对应函数的返回值类型,....>
  • MakeCallback()函数来创建一个回调对象
Callback<int, int, int> callback = MakeCallback(&add);
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */

#include "ns3/core-module.h"

using namespace ns3;

NS_LOG_COMPONENT_DEFINE ("TryCallback");

class A {
public:
    A(Callback<int, int, int> calculator);

    void calculate();
private:
    Callback<int, int, int> m_calculator;
};

A::A (Callback<int, int, int> calculator)
{
    m_calculator = calculator;
}

void
A::calculate ()
{
    int result = m_calculator(5, 6);
    NS_LOG_UNCOND(result);
}

int add(int a, int b)
{
    return a + b;
}

int
main (int argc, char *argv[])
{
    A one(MakeCallback(&add));
    one.calculate();
}

方法的回调(MemPtrCallbackImpl)

  • 定义回调:
Callback<Complex, Complex &> m_complexCalculator;
  • 创建回调对象:
Complex first(1, 3);
Callback<Complex, Complex &> callback = MakeCallback(&Complex::add, &first);

完整程序

/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */

#include <iostream>

#include "ns3/core-module.h"

using namespace ns3;

NS_LOG_COMPONENT_DEFINE ("TryCallback");

class Complex {
public:
    Complex(int a, int b);
    Complex add(Complex & another);
    friend std::ostream & operator <<(std::ostream & out, Complex & c);
private:
    int m_a;
    int m_b;
};

Complex::Complex (int a, int b)
{
    m_a = a;
    m_b = b;
}

Complex Complex::add (Complex & another)
{
    int a = m_a + another.m_a;
    int b = m_b + another.m_b;
    return Complex(a, b);
}

std::ostream & operator <<(std::ostream & out, Complex & c) {
    out << c.m_a << " + " << c.m_b << "i";
    return out;
}

class A {
public:
    A(Callback<int, int, int> calculator);
    A(Callback<Complex, Complex &> complexCalculator);

    void calculate();
    void complexCalculate(Complex b);
private:
    Callback<int, int, int> m_calculator;
    Callback<Complex, Complex &> m_complexCalculator;
};

A::A (Callback<int, int, int> calculator)
{
    m_calculator = calculator;
}

A::A (Callback<Complex, Complex &> complexCalculator)
{
    m_complexCalculator = complexCalculator;
}

void
A::complexCalculate (Complex b)
{
    Complex result = m_complexCalculator(b);
    std::cout << result << std::endl;
}

void
A::calculate ()
{
    int result = m_calculator(5, 6);
    NS_LOG_UNCOND(result);
}

int add(int a, int b)
{
    return a + b;
}

int multiply(int a, int b)
{
    return a * b;
}

int
main (int argc, char *argv[])
{
    Complex first(1, 3);
    Complex second(2, 5);

    A one(MakeCallback(&Complex::add, &first));
    one.complexCalculate(second);//3+8i
}

绑定参数的回调(MakeBoundCallback)

对于对象的方法,由于对象本身就具有存储数据的能力,就无需绑定参数的回调这个概念。因此,NS-3当中并未提供绑定参数的对象方法的回调。

/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */

#include <iostream>

#include "ns3/core-module.h"

using namespace ns3;

NS_LOG_COMPONENT_DEFINE ("TryCallback");

class A {
public:
    A(Callback<int, int> calculator);

    void calculate();
private:
    Callback<int, int> m_calculator;
};

A::A (Callback<int, int> calculator)
{
    m_calculator = calculator;
}

void
A::calculate ()
{
    int result = m_calculator(6);
    NS_LOG_UNCOND(result);
}

int add(int a, int b)
{
    return a + b;
}

int multiply(int a, int b)
{
    return a * b;
}

int
main (int argc, char *argv[])
{
    A one(MakeBoundCallback(&add, 8));
    one.calculate();
}

判断回调是否绑定函数(Callback::IsNull())

/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */

/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */

#include <iostream>

#include "ns3/core-module.h"

using namespace ns3;

NS_LOG_COMPONENT_DEFINE ("TryCallback");

class A {
public:
    A();
    A(Callback<int, int, int> calculator);

    void calculate();

    void
    setCalculator (const Callback<int, int, int>& calculator)
    {
        m_calculator = calculator;
    }

private:
    Callback<int, int, int> m_calculator;
};

A::A(){}

A::A (Callback<int, int, int> calculator)
{
    m_calculator = calculator;
}

void
A::calculate ()
{
    if(m_calculator.IsNull()) {
        NS_LOG_UNCOND("callback is not bind to any function.");
    } else {
        int result = m_calculator(6, 8);
        NS_LOG_UNCOND(result);
    }
}

int add(int a, int b)
{
    return a + b;
}

int multiply(int a, int b)
{
    return a * b;
}

int
main (int argc, char *argv[])
{
    A one(MakeCallback(&add));
    one.calculate();
    one.setCalculator(MakeNullCallback<int, int, int>()); //构造空回调
    one.calculate();
}

回调作为属性(CallbackValue)

程序演示:

/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */

#include <iostream>

#include "ns3/core-module.h"

using namespace ns3;

NS_LOG_COMPONENT_DEFINE ("TryCallback");

namespace ns3 {

  class A : public Object{
  public:
    static TypeId GetTypeId (void);

    A();

    void calculate();

    void
    setCalculator (const Callback<int, int, int>& calculator)
    {
      m_calculator = calculator;
    }

  private:
    Callback<int, int, int> m_calculator;
  };

  A::A(){}

    TypeId
    A::GetTypeId (void)
    {
    static TypeId tid = TypeId ("ns3::A")
      .AddConstructor<A> ()
      .SetParent<Object> ()
      .AddAttribute ("calculator", "help text",
                     CallbackValue (),
                     MakeCallbackAccessor (&A::m_calculator),
                     MakeCallbackChecker ())
            ;
    return tid;
    }

  void
  A::calculate ()
  {
    if(m_calculator.IsNull()) {
      NS_LOG_UNCOND("callback is bind to any function.");
    } else {
      int result = m_calculator(6, 8);
      NS_LOG_UNCOND(result);
    }
  }

  int add(int a, int b)
  {
    return a + b;
  }

  int multiply(int a, int b)
  {
    return a * b;
  }
}

int
main (int argc, char *argv[])
{
    Ptr<A> a = CreateObject<A>();//使用智能指针创建一个A类的实例
    a->SetAttribute("calculator", CallbackValue(MakeCallback(&add)));//为属性calculator指定一个回调函数add
    a->calculate();
}

例子中将之前A当中的有参构造函数删除,此时向A当中指定回调的任务现在由属性框架来完成。因此A必须继承Object类,并且实现GetTypeId()方法来使用属性框架。在GetTypeId()方法中,创建了一个属性叫做”calculator”,其绑定到了成员变量m_calculator上,属性值类型为CallbackValue。该属性默认回调值为空,使用了变量访问器和默认检查器。

12-22 12:14
查看更多