[整理]symbian中活动对象的简单使用

本文介绍Symbian系统中使用活动服务对象(CActive)替代多线程的方法,通过实例展示如何构建一个基于消息驱动的计数器。

symbian官方推荐使用活动服务对象(CActive)来代替多线程的使用,我想这个道理是很明了的,在手机这样的小内存设备里,运行多线程的程序是非常耗资源的,为了节约资源,symbian提供了一个活动服务对象的框架,允许把程序里并发执行对象(其实不是并发,不过宏观上看来是)放在一个线程里面执行,这些并发工作的对象就通过活动规划器(ActiveScheduler)来进行管理.

关于这两个东西的介绍,网上有一大堆的文档,我就不在这里废话了,如何使用呢?这里我先举一个简单的计数器的例子.我选择写一个exe的程序,也就是说程序是以E32Main为入口的.

GLDEF_C TInt E32Main()

{

    CTrapCleanup* cleanup=CTrapCleanup::New();

    TRAPD(error,callInstanceL());

    if (error != KErrNone)

    {

        printf("get error %d/r/n", error);

    }

    delete cleanup;

    return 0;

}

以上的内容是每一个exe文件都应该做的,CTrapCleanup* cleanup=CTrapCleanup::New()建立一个清除堆栈,以便程序在异常退出的时候把清除堆栈里面的资源都释放掉.当然你也可以加上堆检测宏(__UHEAP_MARK,__UHEAP_MARKEND,这里我就不多说了。TRAPDsymbian里面经常使用的宏,功能类似于try,第一个参数是让定义一个错误返回值变量的名字后面就是可能有异常的你写的函数.当这个函数异常时,程序不会crash, 你可以得到异常的原因.可以参考nokia论坛上的一些关于这些使用的文档.

接下来是vcallInstanceL函数,在这个函数里面我来建立ActiveScheduler.

LOCAL_C void callInstanceL()

{

    CActiveScheduler* scheduler = new(ELeave) CActiveScheduler();

    CleanupStack::PushL(scheduler);

    CActiveScheduler::Install(scheduler);

    TRAPD(error,doInstanceL());

    if(error)

    {

        printf("error code=%d/r/n",error);

    }

    else

    {

        printf("OK!/r/n[press any key]");

    }

    CleanupStack::PopAndDestroy(scheduler);

}

这段程序很简单就是创建一个活动规划器,并压入清除栈,然后安装活动规划器,这样就可以用了.再执行真正的实例函数,最后出栈销毁。doinstance(该函数将在最后的代码中给出,主要的功能就是调用我们自己写的活动计数器)我们放到最后来写,现在来构造我们的活动计数器对象。

class TimeCount : public CActive

{

public :

    static TimeCount* NewLC(); // 构造函数

    ~TimeCount();

    void StartL();             // 计数开始

    void ConstructL();

    void RunL();             // 延时事件到达以后的处理函数

    void DoCancel();         // 取消请求提交

    void setDelayTime(int delayTime);

private:

    TimeCount();

    RTimer iTimer;          // 定时器

    int iTimeCount;         // 计数器

     int mTime;            // 计数间隔时间 单位秒

};

 

TimeCount::TimeCount():CActive(0)  // 这里可以设置活动对象的优先级

{

    // 把自己加入活动规划器

    CActiveScheduler::Add(this);

}

 

TimeCount* TimeCount::NewLC()

{

    TimeCount* result = new (ELeave) TimeCount();

    CleanupStack::PushL( result );

    result->ConstructL();

    return result;

}

 

void TimeCount::DoCancel(void)

{

    iTimer.Cancel();

}

 

void TimeCount::setDelayTime(int mTime)

{

    DelayTime = mTime;

}

 

TimeCount::~TimeCount()

{

    Cancel();

    iTimer.Close();

}

 

void TimeCount::StartL()

{

    // 设定定时器状态为每隔mTime秒钟状态完成一次

    iTimer.After(iStatus, 10000 * 100 * mTime);

    // 提交异步请求

    SetActive();

}

 

void TimeCount::ConstructL()

{

    // 初始化计数器和定时器

    iTimeCount = 0;

    User::LeaveIfError(iTimer.CreateLocal());

}

 

void TimeCount::RunL()

{

    // 计数器+1以后继续提交延时请求事件

    printf("The Count is ->>%d", iTimeCount++);

    StartL();

}

每一个活动服务对象都有一个iStatus来标识当前对象的状态.在这里我们把iStatus设定为iTimer.After(iStatus, 10000 * 100 * mTime);也就是定时器定时mTime秒钟以后iStatus发生改变,这个时候活动规划器会收到这个状态的改变,从而调用相应活动对象的处理函数,也就是RunL函数.RunL函数里面进行计数和输出,然后调用startL重新设置定时器和对象状态,再提交给活动规划器。这样mTime秒钟以后活动规划器会再次调用RunL函数.一直这样重复,这样就达到了计数器的效果。

最后我们来写doinstanceL函数

LOCAL_C void doInstanceL()

{

    TimeCount* timeCount = TimeCount::NewLC();

    // 每隔一秒钟打印一次

    TimeCount->setDelayTime(1);

    TimeCount->StartL();

    CActiveScheduler::Start();

    CleanupStack::PopAndDestroy(1);

}

创建好对象以后,加上CActiveScheduler::Start()程序就开始运行了,这句话告诉活动规划器该等待对象的状态的改变了(正常情况下,一旦CActiveScheduler::Start()之后,程序直到CActiveScheduler::Stop()才能终止运行),在这里就是timeCountiStatus的改变.iStatus改变并调用了RunL以后,继续等待iStstus的改变,这样我们使用活动对象的计数器就能够通过消息驱动运行起来了.

这里的CActiveScheduler只管理了一个CActive对象,就是timeCount,可以用类似的方法实现多个CActive,并且都加入CActiveScheduler,CActiveScheduler将会等待所有加入它的CActive的状态的改变,其中有一个的状态改变就会去执行对应的活动对象的处理函数,当状态同时发生的时候,会通过对象的优先级来决定先调用谁的RunL函数.CActiveScheduler也是非抢占式的,当一个RunL函数还没有执行完的时候,如果另一个CActive的状态改变,会等待RunL执行完以后再执行另一个CActive的处理函数(正因为这一点,所以通常RunL函数不能设计为长函数,否则会阻塞活动对象)。

 本文在网上根据网上用人提供的原本阅读学习而成,可算是转载类型的。

### 光流法C++源代码解析与应用 #### 光流法原理 光流法是一种在计算机视觉领域中用于追踪视频序列中运动物体的方法。它基于亮度不变性假设,即场景中的点在时间上保持相同的灰度值,从而通过分析连续帧之间的像素变化来估计运动方向和速度。在数学上,光流场可以表示为像素位置和时间的一阶导数,即Ex、Ey(空间梯度)和Et(时间梯度),它们共同构成光流方程的基础。 #### C++实现细节 在给定的C++源代码片段中,`calculate`函数负责计算光流场。该函数接收一个图像缓冲区`buf`作为输入,并初始化了几个关键变量:`Ex`、`Ey`和`Et`分别代表沿x轴、y轴和时间轴的像素强度变化;`gray1`和`gray2`用于存储当前帧和前一帧的平均灰度值;`u`则表示计算出的光流矢量大小。 #### 图像处理流程 1. **初始化和预处理**:`memset`函数被用来清零`opticalflow`数组,它将保存计算出的光流数据。同时,`output`数组被填充为白色,这通常用于可视化结果。 2. **灰度计算**:对每一像素点进行处理,计算其灰度值。这里采用的是RGB通道平均值的计算方法,将每个像素的R、G、B值相加后除以3,得到一个近似灰度值。此步骤确保了计算过程的鲁棒性和效率。 3. **光流向量计算**:通过比较当前帧和前一帧的灰度值,计算出每个像素点的Ex、Ey和Et值。这里值得注意的是,光流向量的大小`u`是通过`Et`除以`sqrt(Ex^2 + Ey^2)`得到的,再乘以10进行量化处理,以减少计算复杂度。 4. **结果存储与阈值处理**:计算出的光流值被存储在`opticalflow`数组中。如果`u`的绝对值超过10,则认为该点存在显著运动,因此在`output`数组中将对应位置标记为黑色,形成运动区域的可视化效果。 5. **状态更新**:通过`memcpy`函数将当前帧复制到`prevframe`中,为下一次迭代做准备。 #### 扩展应用:Lukas-Kanade算法 除了上述基础的光流计算外,代码还提到了Lukas-Kanade算法的应用。这是一种更高级的光流计算方法,能够提供更精确的运动估计。在`ImgOpticalFlow`函数中,通过调用`cvCalcOpticalFlowLK`函数实现了这一算法,该函数接受前一帧和当前帧的灰度图,以及窗口大小等参数,返回像素级别的光流场信息。 在实际应用中,光流法常用于目标跟踪、运动检测、视频压缩等领域。通过深入理解和优化光流算法,可以进一步提升视频分析的准确性和实时性能。 光流法及其C++实现是计算机视觉领域的一个重要组成部分,通过对连续帧间像素变化的精细分析,能够有效捕捉和理解动态场景中的运动信息
微信小程序作为腾讯推出的一种轻型应用形式,因其便捷性与高效性,已广泛应用于日常生活中。以下为该平台的主要特性及配套资源说明: 特性方面: 操作便捷,即开即用:用户通过微信内搜索或扫描二维码即可直接使用,无需额外下载安装,减少了对手机存储空间的占用,也简化了使用流程。 多端兼容,统一开发:该平台支持在多种操作系统与设备上运行,开发者无需针对不同平台进行重复适配,可在一个统一的环境中完成开发工作。 功能丰富,接口完善:平台提供了多样化的API接口,便于开发者实现如支付功能、用户身份验证及消息通知等多样化需求。 社交整合,传播高效:小程序深度嵌入微信生态,能有效利用社交关系链,促进用户之间的互动与传播。 开发成本低,周期短:相比传统应用程序,小程序的开发投入更少,开发周期更短,有助于企业快速实现产品上线。 资源内容: “微信小程序-项目源码-原生开发框架-含效果截图示例”这一资料包,提供了完整的项目源码,并基于原生开发方式构建,确保了代码的稳定性与可维护性。内容涵盖项目结构、页面设计、功能模块等关键部分,配有详细说明与注释,便于使用者迅速理解并掌握开发方法。此外,还附有多个实际运行效果的截图,帮助用户直观了解功能实现情况,评估其在实际应用中的表现与价值。该资源适用于前端开发人员、技术爱好者及希望拓展业务的机构,具有较高的参考与使用价值。欢迎查阅,助力小程序开发实践。资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值