Symbian和UIQ开发教程(续)

在Symbian中开发C++的注意:
1. 在Symbian中可以使用C++的语法, 除了异常(try-catch)与STL外
不支持异常是因为如果使用标准C++的异常机制会比较费系统资源, 所以Symbian提供了自己的异常框架,那就是(Leave-TRAPED).
不支持STL是因为STL使用的是模板, 编译时会进行扩展, 这样增大了可执行文件的大小
2. Symbian中对C中的基本类型提供了另一套名字, 如unsigned int 可以写成TUint等, 你可以使用老的方式, 但是为了代码的可读性, 最好使用Symbian中自定义的类型. 自定义的类型一般是前面加一个T, 如TInt来代替int (typedef signed int TInt), 它对所有的基本类型都使用了这样的Typedef, 不过要注意的是 TChar是一个类, 另外还定义了一个TRefByValue, 这个可看成是一个类的引用
3. Symbian中API的对符串使用描述符(Descriptor)来保存,你当然可以继续使用普通C语言的形式, 但是调用API时需要对它进行转换.
另外Symbian中使用的字符串是Unicode类型的.
Descriptor中保存了串的长度信息, 避免内存访问越界. 有两个基类TDes 和TDesC派生出其它字符串类, 它们相当于 wchar_t* 和 const wchar_t*.
如果想定义一个字符串常量, 使用 _L("字符串") 就可以
如果想定义一个8bit的字符串常量, 使用_L8("字符串")
Symbian中描述符与C++的字符类型对应关系:
名称: Symbian C++
指针 TPtr/TPtrC wchar_t*/const wchar_t*
数组: TBuf/TBufC wchar_t[]/const wchar_t[]
内存堆: HBufC8 new wchar_t[]
常量: _L("字符串") "字符串"
4. 在Symbian中 Symbian中系统API都是类形式提供的. Symbian使用的是C/S架构, 多数操作需要先连接到服务器再进行操作, 如打开文件, 普通开发中使用fopen就可以, 而在Symbian中, 需要这样做:
RFs fs; // 声明服务器连接对象
RFile file; // 定义文件操作对象
if(fs.Connect() != KErrNone ) // 连接到文件服务器
return false;
if( file.Open(fs,L"Filename.txt",
EFileStream|EFileWrite|EFileShareAny) == KErrNone ){
// 打开文件
做其它操作
file.Close(); // 关闭文件
}
fs.Close(); // 关闭到文件服务器的连接
对多数系统资源的使用多数也是这样. 这个是与普通C中不同的地方,开发时要注意一下SDK文档.
5. Symbian中资源是有限的, 如堆栈只有8k, 所以应该尽量在堆中分配内存, 堆栈的错误很难检查.
但是频繁的new, 会导致内存碎片, 从而降低程序的性能, 并有可能引起系统不稳定.
6. 由于资源有限, 所以创建类对象时可能失败, 为了避免由于构造到一半时失败而引起的资源泻漏, Symbian中对于对象的构造使用两步构造的方法. 构造函数中不申请资源, 另外定义一个Construct()或ConstructL()函数在里面进行其它的初始化操作.
下面是一个例子:
CCommandsView::CCommandsView()
{
m_p = NULL; // 只初始化变量, 不分配资源
}
CCommandsView::ConstructL()
{
m_p = new(ELeave) char[100]; // 分配资源, 可能会分配失败而退出
}
CCommandsView* CCommandsView::NewLC(CQikAppUi& aAppUi)
{
CCommandsView* self = new (ELeave) CCommandsView(aAppUi); // 只构造
CleanupStack::PushL(self);
self->ConstructL(); // 进行其它的初始化操作
return self;
}
7. Symbian中提供了cleanup stack来代替标准c++的异常, 如果分配一个资源, 应该把它放到cleanup stack中, 避免异常退出时引起的资源问题(如上面的CleanupStack::PushL(self)).
如下:
CCommandsView* p1 = CCommandsView*::NewLC(ui); // 申请并放到clean up stack 中
CCommandsView* p2 = CCommandsView*::NewLC(ui);
CCommandsView* p3 = CCommandsView*::NewLC(ui);
CleanupStack::PopAndDestroy(3); // 释放
在每次NewLC中, 都把当前的资源放到cleanup stack中,最后的PopAndDestroy(3)表示删除前面三个放进去的资源, 相当于执行下面这句话
delete p1;delete p2; delete p3;
如果在p2->NewLC时产生了异常, 那异常会退到上一层, 一直到TRAPD的地方, 然后在这里p1 的资源被释放. 这就是cleanup stack的意义(当产生异常时, 保证资源被释放)
如果一个函数名后面是L结束,表示这个函数是会leave的, 如果它是LC结束,表示它是会leave, 但是它在里面已经把指针放到cleanup stack中了. 如果没有这两个, 表示这函数不会产生异常,也没有把自己放到cleanup stack中.

6. Symbian中提供了活动对象(active object, 一个调度器管理多个对象, 当某个对象激活时,调度器运行它, 从而实现依并发功能) 与清除堆栈(cleanup stack, 这个是用来代替C++异常的东东)两个功能, 对于系统线程(如UI中点击时的处理函数等)默认是创建好这两个东西. 如果自己创建了线程并想使用它们的话, 需要自己创建.
下面是一个例子:
TInt CMyClass::StartAppThreadFunction(TAny* /*aParam*/)
{
// 创建活动调度器
CActiveScheduler * scheduler = new CActiveScheduler();
if( scheduler == NULL )
return KErrNoMemory;
CActiveScheduler::Install(scheduler);
// 创建清除堆栈
CTrapCleanup * cleanup = CTrapCleanup::New();
TInt err;
if( cleanup == NULL )
err = KErrNoMemory;
else
TRAP( err, RunFunctionL() ); // 运行部分
delete cleanup;
delete CActiveScheduler::Current();
return err;
}
9 Symbian 9 中, 每个api必须有相应的能力才能调用, 能力的指定在签名中,开发时必须注意
10 Symbian中 dll不可以使用静态变量或是全局变量, 如果你希望在dll中保存一些全局的东西可以考虑tls

没有异常支持及stl支持对于多数开发者来说还是比较方便的
但是:
symbian中并完全支持标准c库的函数 (多数c库的函数是通过封装symbian的api来实现的, 可能会有少量的api没有封装)
栈只有8k
及dll中不可以有静态或全局变量 这个使在程序中直接使用第三方库提供了困难
如果想使用第三方库时需要考虑这点

转自http://wushuangli.blog.hexun.com/6625886_d.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值