Symbian 的 TCallBack

博客介绍了Symbian中一些API接口使用TCallBack类型参数作为回调函数,若指定类的成员函数需写套路代码。还给出一种不太满意但能省些代码的方法,通过模板结构体MemCBData来摆脱部分套路代码,介绍了其实现和使用示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

symbian中的一些API接口都需要一个TCallBack类型的参数作为回调函数使用, 如果你需要指定到一个类的成员函数, 一般我们要写一段套路代码,
1.  先定义一个静态函数, 接收一个void*指针,
2.  然后在这个函数中将这个指针转换成某个class的指针, 然后调用class中的某个成员函数,
例如
 class  CFoo
 {
  void start_timer()
  {
    iTimer = CPeriodic::NewL(EPriorityLow);
    iTimer->Start(5 * 1000000, 5 * 1000000, TCallBack(CFoo::entry, this);  #1
  }

   //#2  公式化代码
   static TInt entry(void * p)
   {
          CFoo * f = static_cast<CFoo*>(p);
          return f->Timeout();       
   }
 
   TInt Timeout()
   {
       do_sth();
       return 0;
   }
 };



例如上面的例子, 需要启动一个Timer, 在#1处将CFoo::entry静态函数地址和一个this指针赋给TCallBack,
我们必须提供一个静态函数entry, 其中进行一个强制转换, 然后调用我们的成员函数Timeout.

#2处的套路代码写一次还可以接收, 写多了确实比较麻烦, 下面是一个我并不满意的方法可以摆脱#2.
优点是并没有动态内存分配, 在Symbian上分配内存实在是胆战心惊, 缺点是这个MemCBData需要作为一个class的成员变量.
因为在Callback发生时这个对象必须存在, 如果VC6支持成员函数作为模板参数argument, 那么MemCBData就无需作为class成员变量. 但是....

无论如何, 至少可以省写几行代码, (好像也省不了太多) ,  这也就是这个class的目的.

template<class T>
struct MemCBData
{
public:
    void assign(T* p, TInt (T::*mf)() )
    {
        this->p_ = p;
        this->mf_ = mf;
    }
    
    operator TCallBack()        // intended not const
    {
        assert(p_);
        assert(mf_);
        
        return TCallBack(&invoker, this);
    }
    
private:
    T * p_;
    TInt (T::*mf_)();

    static TInt invoker(void* aPtr);
    TInt call()
    {
        return (p_->*mf_)();
    }
};

template<class T>
TInt MemCBData<T>::invoker(void * ptr)
{
    MemCBData * c = static_cast<MemCBData*>(ptr);
    return c->call();
}


使用例子:

 class  CFoo
 {

  MemCBData<CFoo> cb1;
  MemCBData<CFoo> cb2;

  CPeriodic iTimer1; iTimer2;
   
  void start_timer()
  {
    iTimer1 = CPeriodic::NewL(EPriorityLow);
    iTimer2 = CPeriodic::NewL(EPriorityLow);

    //time1 触发Timeout1 函数, time2触发Timeout2函数

    cb1.assign(this, CFoo::Timeout1);
    iTimer1->Start(5 * 1000000, 5 * 1000000, cb1);

    cb2.assign(this, CFoo::Timeout2);  
    iTimer2->Start(10 * 1000000, 10 * 1000000, cb1);
  }

   TInt Timeout1()
   {
       do_sth();
       return 0;
   }

   TInt Timeout2()
   {
    return 1;       
   }
 };

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值