Symbian OS internals: Active and CAyncCallBack

收藏
这一节讲讲活动对象的extension 用例 CAyncCallBack。

怎么使用:

一般作为成员变量。

 Class A

{

private:

CAsyncCallBack* iCall;

}

找一个初始话的地方把它先构造出来。

A::PreLayoutDynInitL()

{

    iCall = new (ELeave) CAsyncCallBack(
                                    TCallBack( LaunchDlgCallback, this ),
                                    CActive::EPriorityStandard );

}

因为CAsyncCallBack是派生于CAtive的, 这句话就是相当于Active的构造,只不过要传递一个TCallBack对象进去,看看他的构造函数

 inline TCallBack(TInt (*aFunction)(TAny* aPtr),TAny* aPtr); 一目了然, 一个函数地址,一个对象地址全传给TCallBack对象了。

有读者就问,那是没时候激活活动对象啊,也就是说你在哪setactive的啊?

继续看怎么用。 。。

A::HandleCommandL ()

{

if (!iCall->IsActive())

{

iCall->Call();

}

}

在此说明一点, 上面的例子是AsyncCallBack的典型使用案例,因为在Gui的事件处理函数 比如像handleWsEventL 或者offereyEvent

或者handleCommand这些函数都是运行在CCoeEnv这个活动对象RunL里面的,为了不阻塞该Runl所以才要把一些需要等待的操作用AsyncCallBack的方式移出到别的RunL中执行,这个例子就是如此, 我们需要用AsyncCallBack去开启一个模态对话框,而这个对话框必要在事件响应函数HandleCommandL里面开启。根据活动对象的原理iCall->Call(); 并不阻塞元函数的例程。

好, 再往下看。

iCall->Call(); 就相当于Active的 SetActive()了,但是特殊之处是 因为这个AsyncCallBack是继承于 CAsyncOneShot的,所以他的call里面实际有自激活的过程iThread.RequestComplete(pS,0); KErrNone = 0,即给当前线程信号量并且激活active。这样的话在ccoeenv的runl运行完,就可以近 AsyncCallBack的runL了。

RunL()

{

调用TCallBack的handler function.

}

因为之前的handler的地址在构造的时候都已经传入,所以很简单在调回去。

这里补充只是, 回调用static的函数获得全局地址,还有void指针的概念如下:

void(类型)指针,是一种特殊的指针,它足够灵巧的指向任何数据类型的地址空间。当然它也具有一定的局限:

在我们要取得指针所指地址空间的数据的时候使用的是 ‘*’操作符,程序员必须清楚了解到对于void指针不能使用这种方式来取得指针所指的内容。因为直接取内容是不允许的。而必须把void指针转换成其他任何valid数据类型的指针,比如char,int,float等类型的指针,之后才能使用'*'取出指针的内容。这就是所谓的类型转换的概念。

最后在A里面做地址转换:

TInt A::LaunchDlgCallback( TAny* aDlg )
    {
    A* dlg =
        static_cast<CWVSettingsUIServerListDialog*>( aDlg ); 
    TRAP_IGNORE( dlg->DoLaunchCorrectDialogL() ); //模态对话框 会wait住当前线程。

    return EFalse;
    }

 在这里说一下为什么要用static的函数,因为callback使用系统,那么如果用类成员函数的话,会隐藏this指针在里面,调用还得this->B()这样的话系统怎么知道this,所以要用static全局地址。这样不会通过this,而且用static还能保证干净的全局地址空间,作用域就是当前编译单元。然后callback你没有this指针的话又不行,因为你最终还要用成员函数,所以TCallBack要求你在用一个this指针作为参数传递过去,这样系统既知道你的函数地址还知道你的对象地址,其实他是把你转过来的对象地址扔到你的callback函数里,这样你回调函数里一地址转换不久可以的到this了么。

 所以这里的handler函数的封装模型就是  B(TAny*) ; TCallBack(B, TAny*);


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/weiehome/archive/2009/08/17/4455246.aspx

你可能感兴趣的:(活动,OS,callback,float,Symbian,extension)