以文本方式查看主题

-  曙海教育集团论坛  (http://sun4.cn/bbs/index.asp)
--  Symbian开发  (http://sun4.cn/bbs/list.asp?boardid=46)
----  symbian开发介绍  (http://sun4.cn/bbs/dispbbs.asp?boardid=46&id=2052)

--  作者:wangxinxin
--  发布时间:2010-12-3 14:50:05
--  symbian开发介绍
symbian操作系统与普通pc的不同是:
  symbian上内存不够多 ,并且cpu速度慢,所以开发的话需要考虑到节省内存的原则 另外就是分配内存失败时的处理 在这点pc基本上不用考虑 因为有真实内存加上虚拟内存 够用的
  symbian操作系统可能运行好几个月 但是你的程序随时可能因为异常而退出 退出时释放程序使用的内存及其它相关资源就相当重要
  
界面开发最简单的方法是使用c++ 把相关的图形操作使用类来封装,所以symbian的sdk以c++ 类库形式提供 如果你还是使用c 那还是赶紧学习c++

由于symbian运行的环境有限,所以为了提高性能减少资源使用 symbian对标准c++进行了一定的修改,其中最明显的是去掉了异常处理机制

另一个就是对模板进行了简化 当然模板方面在语言开发中不会有不同 只是修改了它的实现 这个可以不用管 只是像c++中的模板一样使用好了

symbian在语言级不支持异常,但是以库与宏的形式来提供对导常的支持
throw 对应于 User::Leave或是leave相关函数
try{}catch(...){}对于于TRAP和TRAPD宏 TRAPD宏与TRAP只是增加了变量定义过程 这两个没有区别

另外 由于资源有限,所以有些程序可能因为不正常的使用资源而死掉 或是因为资源使用完而无法正常执行
这时 虽然可以自己增加错误处理过程 但是这样的过程太多了 如内存分配 每次分配完 都要检查是不是成功 没有成功就释放资源程序退出 这样代码量就很大 而在实时系统中 需要的是代码少而精
所以 symbian提供了cleanupstack(清除堆栈)机制
当你申请了资源后 把它Push到cleanupstack中 那后面如果某个申请失败了 可以直接调用User::Leave退出程序 操作系统会自动帮你释放你申请的资源 这样代码量就减少
如果已经成功的使用完资源了 需要自己释放 那就调用PopAndDestroy手动释放它
  
为了保证程序退出时用户申请的资源全部释放(主要是内存) 所以symbian同时提供了heap marking机制,程序开始时标记当前堆信息 退出时检查并释放没有释放的堆
  
  总之就是symbian开发中需要自己处理下面的事情:
   trap harness,cleanup stack,leave,heap marking


其实跟c++比起来 symbian对释放资源的操作通过cleanupstack进行了支持
只是需要自己手动的把资源放到cleanupstack中
这样可以认为是c++的手动管理资源与java的自动资源管理的一个折中
第一个控制台下的hello world程序
很多语言都是从hello world 开始 学习symbian也不例外 下面从一个简单的hello world程序开始 介绍symbian的特点
CODE
//hellotext.cpp
#include
#include
LOCAL_D CConsoleBase* gConsole;
//  Real main function
void MainL()
{
TBuf    helloWorld(_L("hello"));
helloWorld.Append(_L("World"));
gConsole->Printf(helloWorld);
// 可以把上面三句改成gConsole->Printf(_L"hello world");
}
//  Console harness
void ConsoleMainL()
{
gConsole    = Console::NewL(_L("Hello Text"),
         TSize(KConsFullScreen,KConsFullScreen));
CleanupStack::PushL(gConsole);
MainL();
User::After(5000000);
CleanupStack::PopAndDestroy(gConsole);
}
GLDEF_C TInt    E32Main()
{
__UHEAP_MARK;
CTrapCleanup* cleanupStack  = CTrapCleanup::New();
TRAPD(error,ConsoleMainL());
__ASSERT_ALWAYS(!error,User::Panic(_L("SCMP"),error));
delete cleanupStack;
__UHEAP_MARKEND;
return 0;
}


编译与运行
symbian的编译要求比较奇怪
它需要一个bld.inf文件与一个mmp文件
bld.inf声明build的相关信息 通常只包括这次build会引用到的mmp文件
.mmp文件保存工程与makefile相关的信息 用于具体的build过程 它也叫makmakefile project ,也就是创建makefile的文件
bld.inf的文件名是固定的
.mmp文件的文件名则根据不同的工程而起不同的名字
下面是hellotext工程中这两个文件的内容
CODE
//  BLD.INF
PRJ_MMPFILES
hellotext.mmp
CODE
//  hellotext.mmp
TARGET      HelloText.exe
TARGETTYPE  exe
SOURCEPATH  .
UID         0
SOURCE      hellotext.cpp
USERINCLUDE .
SYSTEMINCLUDE   \\epoc32\\include
LIBRARY     euser.lib
把上面两个文件保存到与hellotext.cpp相同的目录下
编译过程:
1 打开一个dos窗口
2 cd 到hellotext.cpp所在目录
3 运行下面命令
bldmake bldfiles
abld build wins udeb
运行完后 你就可以到
epoc/release/wins/udeb目录下查找hellotext.exe文件
//  BLD.INF
PRJ_MMPFILES
hellotext.mmp
bld.inf只是声明这个build需要调用hellotext.mmp模块

CODE
// hellotext.mmp
TARGET HelloText.exe 生成的应用程序名是hellotext.exe
TARGETTYPE exe 生成的应用程序类型是exe类型,在symbian上可运行的程序类型有exe与app,另外还支持生成其它类型文件,如dll
SOURCEPATH . 在哪里查找源文件 这里指示是在当前目录下
UID 0 对exe程序不需要指定,这里写0
SOURCE hellotext.cpp 生成应用程序需要的源文件,这里是hellotext.cpp 可以有多个source 一直照这样的格式写就可以
USERINCLUDE . 用户自定义的头文件在哪里查找 这里是当前目录
SYSTEMINCLUDE \\epoc32\\include 系统头文件在哪里查找 一般都是这个值
LIBRARY euser.lib 需要链接的库 这是euser.lib

symbian的开发环境是使用perl开发的
所以需要有一个确定的文件名声明工程内容 这就是bld.inf
bldmake编译时先读bld.inf 看需要哪个文件指导编译过程
然后对mmp文件进行转换,生成makefile及其它相关的编译规则文件 同时在当前目录下生成abld.bat文件
后面就是使用abld进行具体编译
bld.inf意义就是 build info.编译信息
mmp文件就是 makmake file
bldmake 就是build make info


bldmake bldfiles 创建build files
abld build wins udeb 创建win simulator unicode debug 版本

另外可能用的其它两个命令是
bldmake clean 清除生成的build file,这在改变mmp文件后应该做
abld reallyclean 清除生成的目标文件(.o) 这在改变源文件内容后使用


symbian 模拟器样子
在命令行下输入epoc得到
如果没钱买智能手机 如p910 那可以拿这个来体会一下效果



刚才编译好的程序的运行
运行epoc/release/wins/udeb/hellotext.exe 看到
没有抓图工具 无法上传
代码说明
因为手机上没有dos或是xterm窗口,所以需要声明一个console类,
打开一个控制台窗口
LOCAL_D CConsoleBase* gConsole;
//  Real main function
void MainL()
{
控制台打印
gConsole->Printf(_L"hello world");
}
//  Console harness
void ConsoleMainL()
{
NewL类似标准c中的new 由于symbian中没有异常,
使用leave trapd代替标准c++中throw catch,
所以如果函数可能会leave的话 函数名后会加上一个L   
gConsole    = Console::NewL(_L("Hello Text"),
         TSize(KConsFullScreen,KConsFullScreen));
symbian中为了避免资源泻漏 使用cleanupstack把需要释放的内容放到cleanupstack中,
当程序非法退出时 symbian操作系统会自动通过cleanupstack来对资源进行释放
保证资源的释放放是重要的
因为symbian可用的资源并不多 内存现在最多也就16M
而它可能一直运行好几个月(想看如果你不常关机的话)
CleanupStack::PushL(gConsole);
调用自己的函数
MainL();
停止5秒 让你看到屏幕显示
User::After(5000000);
手动释放刚才申请的资源
CleanupStack::PopAndDestroy(gConsole);
}
symbian中exe程序的入口定义如下GLDEF_C TInt    E32Main
而不是标准C中的的main
可以认为symbian自己定义了main函数,
然后在里面进行自己的初始化
初始化完后再调用E32main
(在psos下开发时也是这样 psos的入口函数是root 在其它实时系统开发与普通系统不同
因为可能需要特殊的初始化 )
GLDEF_C TInt    E32Main()
{
__UHEAP_MARK;定义堆保护 保证程序退出时会释放资源
创建清除堆栈类
CTrapCleanup* cleanupStack  = CTrapCleanup::New();
TRAPD(error,ConsoleMainL());  这个相当于标准c++中的catch(...)
__ASSERT_ALWAYS(!error,User::Panic(_L("SCMP"),error));
delete cleanupStack;
__UHEAP_MARKEND; 堆保护完成 在这里释放掉所有内存
return 0;
}
结合上面的代码看symbian提供的机制
Leave , trap,cleanupstack ,heapmarking 都存在了

这是一个典型的symbian程序都会使用到的功能


函数是不是会Leave 这个在symbian中是以函数名的形式提供
函数名后面是L的表示它会Leave 函数名后面是LC的表示它会Leave,并且已经把指针push到cleanupstack中了

leave的情况:
是不是任何情况都会Leave呢
当然不是 只有资源申请失败或是操作失败时时会Leave 在系统库提供的函数是这样的

一般它也会提供不Leave的相同功能的函数
如Defined in TDesC8: 看TDesc8的类说明
Alloc(), AllocL(), AllocLC(), Compare(), CompareC(), CompareF(), Find(), Find(), FindC(), FindC(), FindF(), FindF(), Left(), Length(), Locate(), LocateF(), LocateReverse(), LocateReverseF(), Match(), MatchC(), MatchF(), Mid(), Mid(), Ptr(), Right(), Size(), operator!=(), operator<(), operator<=(), operator==(), operator>(), operator>=(), operator[]()

这里提供了Alloc()和AllocL()
看它们的说明
Alloc()
HBufC8* Alloc() const;
Description
Creates a new 8 bit heap descriptor and initialises it with a copy of this descriptor\'s data.

Return value
HBufC8* A pointer to the new 8 bit heap descriptor, if creation is successful. NULL, if creation of the descriptor fails.