Symbian笔记.docx

上传人:b****1 文档编号:10213143 上传时间:2023-05-24 格式:DOCX 页数:18 大小:48.11KB
下载 相关 举报
Symbian笔记.docx_第1页
第1页 / 共18页
Symbian笔记.docx_第2页
第2页 / 共18页
Symbian笔记.docx_第3页
第3页 / 共18页
Symbian笔记.docx_第4页
第4页 / 共18页
Symbian笔记.docx_第5页
第5页 / 共18页
Symbian笔记.docx_第6页
第6页 / 共18页
Symbian笔记.docx_第7页
第7页 / 共18页
Symbian笔记.docx_第8页
第8页 / 共18页
Symbian笔记.docx_第9页
第9页 / 共18页
Symbian笔记.docx_第10页
第10页 / 共18页
Symbian笔记.docx_第11页
第11页 / 共18页
Symbian笔记.docx_第12页
第12页 / 共18页
Symbian笔记.docx_第13页
第13页 / 共18页
Symbian笔记.docx_第14页
第14页 / 共18页
Symbian笔记.docx_第15页
第15页 / 共18页
Symbian笔记.docx_第16页
第16页 / 共18页
Symbian笔记.docx_第17页
第17页 / 共18页
Symbian笔记.docx_第18页
第18页 / 共18页
亲,该文档总共18页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

Symbian笔记.docx

《Symbian笔记.docx》由会员分享,可在线阅读,更多相关《Symbian笔记.docx(18页珍藏版)》请在冰点文库上搜索。

Symbian笔记.docx

Symbian笔记

第一部分Symbian开发环境

一、开发与编译

1、运行一个已经存在的Symbian程序

1)进入group目录

2)Bldmakebldfiles

3)abldmakefilewinsudeb

要搞清楚一下命令的区别,已经symbian安装目录下的文件夹结构

Abldbuildvc6

Abldmakefilevc6

产生VC6的项目文件和工作空间文件(.dsp和.dsw)

Epoc32\Build子文件夹中

Abldbuildwinsudeb//编译针对WINS平台的调试版本

2、建立一个自己的symbian程序

通过symbian自带的工具Applicationwizard

3、将Symbian应用程序安装到手机上

1、进入group

2、Bldmakebldfiles

3、Abldbuildarmiurel

4、进入sis目录

5、修改*.pkg文件中的路径

6、Makessis*.pkg

7、通过蓝牙传输到手机中

二、模拟器

1)模拟器有两种版本:

1、包括符合调试信息

C:

\Symbian\8.0a\S60_2nd_FP2_SC\epoc32\release\wins\udeb\EPOC.EXE

2、发行版本

C:

\Symbian\8.0a\S60_2nd_FP2_SC\epoc32\release\wins\urel\EPOC.EXE

2)在命令行中运行模拟器:

Epro

Epro-rel

三、工程文件

组件定义文件bld.inf

●列出组件中所有的工程mmp

●给出附加的编译命令

项目定义文件*.mmp

●描述工程

●定义资源文件和应用程序附加文件

Bld.inf

//Helloworldbld.inf

PRJ_MMPFILES

//列出项目所需要的.mmp文件

HelloWorldBasic.mmp

Bldmake工具处理当前目录中的组件定义文件(bld.inf),并且生成批处理文件abld.bat和一些批处理生成文件(.make)。

使用bldmakeclean将清除这些文件。

helloworld.mmp

TARGETHelloWorldBasic.app//应用程序的名称,必须具有正确的扩展名

TARGETTYPEapp//文件的类型,app为GUI程序,确定UID1,确定文件是文档还是可执行码

//ChangethesecondnumberheretochangetheUIDforthisapplication

UID0x100039CE0x10005B91//UID2确定文档类型,UID3应用程序标识,唯一

TARGETPATH\system\apps\helloworldbasic//最终生成的应用程序及其组件所在位置

SOURCEPATH..\src//源文件的位置路径

SOURCEHelloWorldBasic.cpp//项目源文件名称

SOURCEHelloWorldBasicApplication.cpp

SOURCEHelloWorldBasicAppView.cpp

SOURCEHelloWorldBasicAppUi.cpp

SOURCEHelloWorldBasicDocument.cpp

SOURCEPATH..\data//资源文件位置路径

RESOURCEHelloWorldBasic.rss//资源文件名称

RESOURCEHelloWorldBasic_caption.rss

USERINCLUDE..\inc//用户头文件位置

SYSTEMINCLUDE\epoc32\include//系统头文件位置

LIBRARYeuser.lib//库文件位置,绝大多数为动态库

LIBRARYapparc.lib

LIBRARYcone.lib

LIBRARYeikcore.lib

LIBRARYavkon.lib

LIBRARYcommonengine.lib

LANGSC//语言

AIFHelloWorldBasic.aif..\aifHelloworldBasicAif.rssc12qgn_menu_demo_cxt.bmpqgn_menu_demo_cxt_mask.bmpqgn_menu_demo_lst.bmpqgn_menu_demo_lst_mask.bmp//指定AIF文件,资源文件,色深,图标文件

//EndofFile

一个计划发布的应用程序还必须提供应用程序信息文件.aif(在开发期间不一定要提供该文件),AIF文件包含图标、所支持语言的可选标题,并指定某些应用程序属性。

如果没有提供AIF文件,应用程序仍然可以运行,只是将取所有系统的默认值

多个SDK的选择:

通过devices命令完成特定SDK的选择

直接运行devices命令将显示当前默认的SDK平台

输入:

devices–setdefault@devicesID来切换不同的设备

在symbian中较小的对象应该放在栈上;所有较大的对象一般都分配在堆上,默认情况下,应用程序的栈大小是8K,堆的大小是1M,可在mmp文件中用EPROCSTACKSIZE来指定栈的大小,EPOCHEAPSIZE来指定堆的大小。

一个最小的GUI应用程序至少需要两个文件:

*.app和*.rsc。

app是可执行文件,rsc是资源编译器产生的二进制资源文件。

为了使系统可以自动识别,所有的GUI应用程序必须遵循一个位置约定—它们必须位于特定的文件夹,例如:

\system\apps\appname\。

,因此,在HelloWorld示例中,应该将前面描述的文件(HelloWorld.app、HelloWorld.rsc、HelloWorld_caption.rsc和HelloWorld.aif)放到名叫\system\apps\HelloWorld的文件夹中。

这个文件夹必须位于c:

或z:

等目标设备驱动器或模拟驱动器的根目录中。

为了正确地实现特定应用程序的功能,可能必须使用其他许多文件,通常将这些必要的文件放在和关键的应用程序文件相同的位置中,及\system\apps\appname\

编译工具自动编译资源文件和AIF文件到\system\apps\appname\目录,并且会在epoc32\data\z保留一个备份。

HelloWorld项目文件和位置

文件夹

内容

\aif

HelloWorld.aif和aif文件的源位图(.bmp)

\data

HelloWorld.rss和HelloWorld_Caption.rss——用于产生HelloWorld.rsc和HelloWorld_caption.rsc的应用程序资源文件

\group

HelloWorld.mmp和bld.inf等平台无关的项目文件

\inc

HelloWorld头文件(.h)和其他通过#include包括的文件,例如HelloWorld.loc和HelloWorld.l01

\sis

通过makesis.exe创建安装文件(.sis)的HelloWorld.pkg包文件。

HelloWorld.sis文件在生成时放于此处

\src

HelloWorld源文件(.cpp)

源文件和头文件

文件名

内容

类模块

注释

HelloWorldApp.h

类和函数声明

应用程序

应用程序创建/初始化

HelloWorldApp.cpp

类和函数定义

HelloWorldAppUi.h

类和函数声明

应用程序UI

命令处理器/控制器

HelloWorldAppUi.cpp

类和函数定义

HelloWorldDocument.h

类和函数声明

文档

拥有数据或应用程序模型

HelloWorldDocument.cpp

类和函数定义

HelloWorldContainer.h

类和函数声明

应用程序的数据视图

显示应用程序的数据

HelloWorldContainer.cpp

类和函数定义

应用程序资源文件

应用程序使用RSS文件(HelloWorld.rss)定义GUI应用程序在屏幕上的显示方式。

定义应用程序外观、行为和功能等信息。

经过资源编译器编译后将生成扩展名为rsc的资源编译文件和扩展名为rsg的头文件,改文件包含一系列符合名/数字常量对,用于标识每一个用户界面元素。

只要引用或使用相关的资源,则必须将该文件通过#include包含在.cpp文件中。

另一个可选的资源文件HelloWorld_caption.rss,用于定义应用程序的标题

其他头文件

HelloWorld.rhr包含可以用于源文件.cpp和资源文件.rss中的任意枚举常量定义。

这些常量特定于某个应用程序,并且一般用于菜单命令、键的处理、视图标识符或对话框中的命令处理。

在带有.rh扩展名的文件中定义UI资源和控件的结构,该结构用于应用程序的资源文件。

控制台应用程序

扩展名为exe,该程序的入口点是E32Main()。

该函数建立内存泄漏宏、清除栈和装置,用于处理callExample()函数中发生的任何异常。

该函数创建一个文本控制台以及从CControlBase中派生而来的控制台类对象,并且调用doExampleL()。

应该在doExampleL()函数中放置或调用测试代码。

文件类型

文件扩展名

描述

.h

C++头文件

.hrh

资源和c++头文件

.cpp

C++源文件

.mmp

Symbian工程文件

.rh

资源头文件

.rss

资源文件

.loc

本地字符串资源头文件

.rsc

编译资源文件(无语言版本)

.rXX

编译资源文件(XX语言代码)

.aif

应用程序信息文件

.app

GUI程序

.lib

库文件

目录结构

模拟器编译后,生成文件在epoc32\release\wins\udeb\z\system\apps\appname

有四个文件*.aif,*.app,*.res,*.res

其中有几个文件备份在epoc32\data\z\apps\appname中

*.aif,*.res,*.res

真机编译后,生成文件在epoc32\release\arm\urel\z\system\apps\appname\*.app

其他文件在epoc32\data\z\system中

手机的盘分c:

e:

存贮卡

z:

rom,存储着操作系统以及所有内置的中间件和应用程序。

Z盘相当于Rom,位于epoc32\release\wins\udeb\z\

C盘相当于Ram,位于epoc32\wins\c被处于激活状态的应用程序和系统本身使用。

4M~32M

在开发时将应用程序放在z:

\system\apps要好于c:

\system\apps7

 

类的命名约定:

用一个前缀大写字母+类名(每个单词第一个字母大写)。

注意:

仅由静态成员函数组成的类没有任何前缀字母

T类:

简单类。

●没有析构函数,通常没有指针(没有分配给堆的内存)

●没有拷贝构造函数(按位拷贝)

●没有公共基类

●往往分配在栈上

C类:

从CBase类派生

●在堆上进行构造

●有一个虚的析构函数

●有一个重载的new运算符(new(Eleave)),该运算符将所有的成员数据初始化为0.

●有一个默认的拷贝构造函数

R类:

资源客户端句柄

●没有公共基类

●在栈上创建

●要在析构函数中关闭资源

M类:

接口类,没有具体的实现,抽象类,只包含纯虚函数。

●没有任何成员数据,无法实例化

●唯一允许使用多重继承的类

静态类:

完全由不能实例化为对象的静态函数组成,这种类是库函数的有用容器。

数据命名约定:

●所有的类属性(成员数据)带有小写字母“i”前缀

●所有函数的形参都带有小写字母“a”前缀

前缀:

E——枚举常量、K——常量、

基本数据类型:

e32def.h

TInt8、TUint8、TInt16、TUInt16、TInt32、TUint32、TInt、TUint

TReal32、TReal64、TReal

TText8、TText16

TBool

TAny

●TUint8常常用于内存数据

●除非迫不得已,尽量不要使用浮点数。

●总使用Symbian操作系统的typedef,不要使用原来的C++类型,以保持编译器的独立性。

函数命名约定:

●首字母大写,每个单词首字母大写

●异常退出函数以L结尾

●将元素保留在清除栈中以LC结尾

C++中创建对象的安全访问的方法:

CMyClass*myPtr=newCMyClass;

if(myPtr)

{

myPtr->Foo();

}

deletemyPtr;

分配不成功则指针为空

在Symbian中:

CMyClass*myPtr=new(ELeave)CMyClass;

myPtr->Foo();

deletemyPtr;

当分配不成功时将抛出异常,下一条指令将不会执行

注意:

C++的delete操作并不把指针置为0,如果要从类的析构函数外部删除成员对象,必须把成员指针设置为NULL。

 

异常处理:

1、捕获装置TRAP、TRAPD

Tinterror;

TRAP(error,TestL());

If(error!

=KErrNone)

{…}

Else

{…}

TRAPD=(Tinterror,TRAP(error,函数名))

要注意:

error变量名不能重复;

注意:

一旦一个TRAP将错误捕获,该错误将不会继续传递到上级,除非用Leave

 

2、用User:

:

Leave(),User:

:

LeaveIfError(),User:

:

LeaveNoMemory()或User:

:

LeaveIfNull()来抛出异常;

Tinterr=TestL();

User:

:

LeaveIfError(err);

User:

:

LeaveNoMemory()不带任何参数,是User:

:

Leave(KerrNoMemory)的高效简写形式,最后,如果传递的指针是NULL,则User:

:

LeaveIfNull()以KErrNoMemory值退出。

 

3、用清除栈来确保异常发生时清除存储在堆上的任何应用程序资源;

注意:

绝对不要将实例数据(类实例拥有的数据)推入清除栈。

CExample*p=newCEmaple();//无内存泄漏,如果产生异常,则实际没有分配内

p->SetCountL(100);//有内存泄漏,如发生异常,则没有析构,造成泄漏

deletep;

CExample*p=newCEmaple();

TRAPD(err.p->SetCountL(100)),由于TRAP开销比较大,这不是最优的解决办法

if(error)

{

deletep;

User:

:

Leave(error);

}

deletep;

新的解决方法

CExample*p=newCEmaple();

//step1把p放在一个可以自动析构的地方

CleanupStack:

:

PushL(p);

p->SetCountL(100);

//step2如果顺利执行到这里,我们把p从自动析构的地方拿出来;没有执行到这也没关系,p会自动被析构

CleanupStack:

:

Pop();

deletep;

CleanupStack:

:

PopDestroy(p);={CleanupStack:

:

Pop();deletep;}

voidFunction2L()

{

CExample*example1=new(ELeave)CExample();

CleanupStack:

:

PushL(example1);

TDate*date1=new(ELeave)TDate();

CleanupStack:

:

PushL(date1);

example1->SetCountL(100);

CleanupStack:

:

PopAndDestory

(2);

}

如果对象是另一个类的成员变量(而不是象x一样的自动变量),那么它会由类的析构函数销毁,因此绝对不应该把成员变量压入清除栈

classCExample

{

private:

CX*iX;

};

CExample:

:

CExample()

{

iX=CX:

:

NewLC();

}

CExample:

:

~CExample()

{

CleanupStatck:

:

PopAndDestroy(iX);

}

CExample*pE=CExample:

:

NewLC();

pE->FunL();

..........

在CExample*pE=CExample:

:

NewLC();执行时,先执行构造函数,ix入栈,然后将pe入栈

结果导致重复删除

---------清楚栈----------

iX;(先析构iX)

pE;(再一次析构了iX)

清除栈上的数组:

p是一个数组指针

CExample*p=newCExample[10];

CleanupStack:

:

PushL(p);

...

CleanupStack:

:

PopAndDestroy();错误:

因为delete

显式的告诉系统,p是数组指针

CleanupArrayDeletePushL(p);

清理时

CleanupStatck:

:

PopAndDestory();

系统用delete[]去"Destroy"p;

清除栈上的R类:

需要能把R类对象推入清除栈,可以有两种选择:

●使用函数CleanupClosePushL();

●直接完成:

产生一个TCleanItem,它由一个指向该R类对象的指针和一个关闭该R类对象的静态函数组成。

RTimertimer;

timer.CreateLocalL();

CleanupClosePushL(timer);

CleanupStatck:

PopAndDestroy();

"Destroy"

timer.Close();

4、两阶段构造对象

注意:

如果提供NewL()或NewLC()函数,良好的习惯通常是,建立私有(或受保护)的对应C++构造函数和ConstractL()。

这可以防止多次调用ConstructL()和覆盖前面已分配成员数据的指针。

同样,私有(或受保护)的C++构造函数可以防止在栈上进行构造,从而防止使用只有部分构造的对象。

私有构造函数可以防止类的派生。

如果希望允许派生,则可以建立受保护的构造函数。

传统的构造

CExample()

{

initL();

}

CExample*p=new(Eleave)CExample//在构造函数中存在异常,发生泄漏

CleanupStack:

:

PushL(p);

p->UnsafeL();

CleanupStack:

:

PopAndDestroy();

修改

CExample()

{

//initL();

}

CExample*p=new(Eleave)CExample

CleanupStack:

:

PushL(p);

p->initL();

p->UnsafeL();

CleanupStack:

:

PopAndDestroy();

我们约定俗成的将二阶段构造函数的名称命名为ConstructL()

staticCExample*Cexample:

:

NewL()

{

CExample*p=new(Eleave)CExample;

CleanupStack:

:

PushL(p);

p->ConstrucL();

CleanupStack:

:

Pop;

returnp;

}

NewL做了两件事:

1、绝对安全的第一阶段标准C++构造(内存没有申请成功不会发生内存泄漏)

2、危险的第二阶段构造ContructL,但是在执行二阶段构造前我们以及将对象指

指针压入清除栈了;

CExample*p=CExample:

:

NewL();

CleanupStack:

:

PushL(p);

p->UnsafeL();

CleanupStack:

:

PopAndDestroy();

staticCExample*Cexample:

:

NewLC()

{

CExample*p=new(Eleave)CExample;

CleanupStack:

:

PushL(p);

p->ConstructL();

returnp;

}

p指针仍然在清除栈上

NewL=NewLC+Pop()

staticCExample*Cexample:

:

NewL()

{

CExample*self=NewLC();

CleanupStack:

:

Pop(self);

returnself;

}

CExample*p=CExample:

:

NewLC();

p->UnsafeL();

CleanupStack:

:

PopAndDestroy();

成员变量用NewL

析构时用delete

 

如何区分是否为异常退出函数?

如果任意行可以异常退出,并且不是本地捕获这个异常退出,这就是一个异常退出函数。

安全内存管理的原则:

●总是从类的析构函数中删除类拥有的对象

●不要删除非拥有对象(也就是那些你只使用的对象)

●不要分配两次(这会导致内存泄漏)

●不要删除两次(这会破坏堆)

●当在析构函数之外删除的时候,立刻让指针归零

●当重新分配的时候,必须使用“删除、指针归零、分配”序列,防止分配失败;

●使用new(ELeave)而不是简单的new;

●在任何一个可能异常退出的函数名尾部加上L

●只在需要的地方使用捕获,比如,函数不能异常退出而且还必须自己处理错误时

●如果A对象只是被一个自动变量指针引用;B将要调用一个可能在该对象的生存期内异常退出的函数,那么就要把该对象压入清除栈

●绝不要把成员变量压入清除栈,使用iMember命名约定来帮助你定位这样的错误

●让所有基于堆的类名都有C开头,并且让它们从CBase派生而来。

使用CBase去零初始化所有的数据,包括所有指针,利用CBase的虚析构函数进行清理

●绝不要从C++构造函数中异常退出

●绝不要从C++构造函数中分配内存

●将可能异常退出的构造函数放入一个第二阶段构造函数中,如ConstructL()

●使用NewL()和NewLC()来封装分配和构造,而不要显式地调用ConstructL()或者C++构造函数,你可以通过把C++构造函数定为私有函数来强化执行这一点。

 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 其它模板

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2