Symbian OS S60 3rd platform 入门导航

Symbian OS S60 3rd platform 入门导航
2010-03-22 14:46
-----------------------------------------------------------------------------
24.对列表控件等控件中的字符串往往是有格式的,所以在初始化或者为赋值时要注意这种格式(比如要加“\t”等)。否则将会迎来莫名其妙的崩溃或者显示不出来,显示不正确。
-----------------------------------------------------------------------------
23. 在.rss文件中定义资源的名字时必须使用小写字母,否则资源会加载失败。
-----------------------------------------------------------------------------
22. 使用描述符Format()字符串时,一.“%S”用大写字母S,二.传入Format的是字符串的指针。
-----------------------------------------------------------------------------
21. 在Symbian 中按下一个按键后,如果这个按键对应了一个消息,那么OfferKeyEventL()与UI中的HandleCommandL()都会被调用,并且即使OfferKeyEventL()先返回了EKeyWasConsumed,HandleCommandL()依然会被调用。
-----------------------------------------------------------------------------
20.  使用signsis签名 .sisx(.sis)时出现:
"file I/O fault,cannot open"错误
使用signsis时发生语法错误。
signsis app.sis app.sisx yourcertification.cer yourkey.key
-----------------------------------------------------------------------------

入门读物
《developing series 60 applications a guide for symbian os C developers》

carbide.c++导入工程(比如示例程序)。File->Import->Symbian OS->Symbian OS Bld.inf file


问题:Symbian使用C函数:

A--Refs:
>Developer Library > Symbian OS Guide > C++ API guide > Base > C Standard Library
部分,里面有详细叙述。

B--在mmp需要中增加:
SYSTEMINCLUDE \epoc32\include\libc
SYSTEMINCLUDE   \epoc32\include\stdapis
LIBRARY estlib.lib
LIBRARY libc.lib
如果需要使用数学函数还需要加上
LIBRARY libm.lib

C--头文件:
#include <stdio.h>
#include <math.h>
#include <string.h>



1.问题:
Undefined symbol: 'CFbsBitmap::CFbsBitmap(void) (??0CFbsBitmap@@QAE@XZ)'   
分析:
Undefined symbol 一般出现在头文件中有相关符号定义,但无法连接到相关库上。
解决:
在.mmp文件中的相关部分加入:
LIBRARY fbscli.lib

2.在.pkg中执行文件复制的语法:
“source” -“!:\destination”
!表示文件安装的目的驱动器
不要忘记destination前面的一横 “-”


3.签名sis用两个工具:
makekeys
signsis
具体使用可以参见两个工具的帮助


4.模拟器与机器的区别:
模拟器上的默认路径与机器上的不同


5.DrawText的崩溃
CWindowGc & gc = SystemGc();
gc.DrawText(_L("Hello"), TPoint(10,10));
解决:需要先设置字体。
gc.UseFont(CCoeEnv::Static()->NormalFont());
gc.DrawText(/*KHello*/_L("Hello"), TPoint(10,10));
gc.DiscardFont();
别忘了DiscardFont()

6.获取文件的完整路径
void GetFullPathName(TDes& aFileName)
{
// Get default drive and path
TParse parse;
TFileName appPath;
TBuf<5> appDrive;
parse.Set(CEikonEnv::Static()->EikAppUi()->Application()->AppFullName(), NULL, NULL);
appPath.Copy(parse.DriveAndPath());
appDrive.Copy(parse.Drive());

// Parse the file name
parse.Set(aFileName, NULL, NULL);
if (parse.Drive().Length() == 0)
{
if (parse.Path().Length() == 0)
{ // Use default path and drive
aFileName.Insert(0, appPath);
}
else
{ // Use default drive
aFileName.Insert(0, appDrive);
}
}
}

使用CEikLable
http://wiki.forum.nokia.com/index.php/How_to_use_CEikLabel

在Symbian中使用标准C库函数
在.mmp文件中加入库estlib.lib即:
LIBRARY estlib.lib

Symbian限制使用STL

C++模板类(例如由STL生成的类)提供了一种在类型安全方式中参数化容器类的方法,然而使用模板将带来复制Code的缺点,因为每当声明不同类型的容器时,就会为复制一份这种类型的容器类Code,这不符合Symbian OS中保持最小代码量的要求。

因此,Symbian希望限制C++模板的使用在“瘦模板”的概念内。此模式使用的是未定义类型(void*)(事实上是等价于void*的TAny*类型)作为参数的基本容器类,容器的Code在此模板化的基类中指定,并通过私继承来访问其具体实现。该模板类为调用者提供了一个类型安全的容器接口,并通过内联方式实现调用。

由此模板类产生的代码量是可以忽略不计的,因为它是内联的,也因为它是参数化的。同样该容器是类型安全的。此概念避免了code的复制,是如此的“苗条”。

正因为只使用瘦模板的约定和效率方面的考虑,在Symbian OS中没有实现STL.

另外,Symbian也不推荐使用多重继承


.mbm生成在指定目录下
.mbg文件生成在..\S60_3rd_FP2_SDK_v1.1\epoc32\include目录下

.pkg指定的文件驱动盘符为“!”时,读取文件方法如下:
e.g.
.pkg:  -"!:\system\apps\Cal_prototype_01_0xE49A95EF\Cal_prototype_01.mbm"
.cpp中路径: "\\system\\apps\\Cal_prototype_01_0xE49A95EF\\Cal_prototype_01.mbm"

与字体相关的库
LIBRARY gdi.lib
LIBRARY fbscli.lib
比如出现类似“Undefined symbol: 'int CFont::DescentInPixels(void) const ...”的错误


symbian系统有两种应用程序格式:
.app
.exe 
Carbide.C++ 可以启动epoc32并自动加载运行.exe文件。.app与.exe文件可以在Menu->Installations中找到并运行。
.app文件已经废弃,不再推荐使用。


老程序在新平台上编译出现:
“undefined symbol:'int E32Main(void)...'”错误。
原因:程序入口不一样。
解决:
#ifndef __SERIES60_3X__
GLDEF_C TInt E32Dll( TDllReason )
{
return KErrNone;
}
#else
GLDEF_C TInt E32Main()
{
return EikStart::RunApplication( NewApplication );
}
#endif
另外加上头文件:
#include <eikstart.h>


模拟器跑起来了,不见程序跑。
1.到模拟器Menu->Installations中找有没有程序,若有则启动之,若没有则往下看。
2.到.mmp文件中将定义生成可执行程序的目标目录(往往是第一个TARGETPATH定义的变量)改为模拟器目录,或者将其注释,以使用默认值。

Carbide调试快捷键
*  Ctrl+Shift+B - 切换当前行的断点状态。注意,该快捷键仅仅在调试界面下是可用的,在Symbian开发界面下是不可用的。
* F5 - 进入当前行函数.
* F6 - 执行当前行.
* F8 - 继续执行.
* Ctrl+R - 执行到当前行.


在使用列表资源时,item的txt字符串中的序号和“\t”不能忘了,否则显示上会有问题。
e.g
RESOURCE ARRAY r_grid_items
{
items =
{
LBUF
{
txt = "opt1";
}
}
}
应改为
RESOURCE ARRAY r_grid_items
{
items =
{
LBUF
{
txt = "0\topt1";
}
}
}


当资源中加入新的位图或者ICON时,仅仅修改.mmp文件和重新build是不够的。.mbg与.mbm文件并不会因为你修改了.mmp文件重新build就更新。必须删除.mbg与.mbm文件再build才可以。只删除.mbg或.mbm文件是不够的,必须都删除。


“undefined reference to”,“undefined symbol”错误,一般是少库引起的。



从api函数中可以看出这个处理过程当windows server发送一个按键的事件便调用AppUI中的HandleWsEventL(),HandleWsEventL()方法首先调用CCoeControl::OfferKeyEventL()如果OfferKeyEvent()返回EKeyWasNotConsumed则继续调用AppUI中的HandleKeyEventL()。如果OffKeyEventL()处理了事件则返回EKeyWasConsumed。

如果想直接调用AppUI中的HandleKeyEventL()可以通过set ECoeStackFlagRefusesAllKeys 来省去调用OfferKeyEventL()。

每次按键都会产生3个事件类型1 EEventKeyDown,2 EEventKeyUp,3 EEventKey;可以从OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)中的aType中得到事件类型。aKeyEvent是一个struct可以得到按键的更多属性,eg:iCode指名按了哪个键(键名在e32keys.h中)iRepeats可以判断是重复按键还是长按键。如果想改变系统的按键重复率可以通过RWsSession 的SetKeyboardRepeatRate方法来设置。


错误“Illegal use of incomplete struct/union/class”可能是由于缺少头文件造成的。
比如在工程中新加入了一个类A,类B中使用类A。在类B的头文件使用了类AFORWARD DECLARATIONS,而在类B的.cpp文件中却没有包含类A的头文件。


为了知道哪些类需要哪些库,有以下三个html格式的文档可以参考:
2.0_libindex.html
3.0_classindex.html
3.0_libindex.html


S60的开发与Qt的开发是相似的,没有类似msdn的文档。大部分疑问应该上网,SDK或者参看各个类的头文件来解决,特别是看头文件这一点和Qt是一样的。

User::LeaveIfError( iFsSession.Connect() );
// Let other sessions to use this. ShareProtected() must be called for
// enabling other other threads in this process to use this handle.
iFsSession.ShareProtected();


关于绘图可以多参考gdi.h中的内容。



iEikonEnv与CEikonEnv::Static()的用法:
1.包含头文件#include <eikenv.h>。否则出现“undefined identifier 'CEikonEnv'”的错误。
2.在.mmp文件中包含库LIBRARY eikcore.lib


After becoming accustomed to the automatic zeroing of all member data for CBase-derived classes, developers often forget to initialize member data for non-CBase-derived classes. Automatic zero-initialization is CBase-specific behavior, so T-classes and all standard types should initialize their data to suitable values on construction.

Developers who write a C-class and then forget to derive it from CBase will leave themselves vulnerable to memory leaks. This is because objects pushed onto the Cleanup Stack that are not derived from CBase are pushed as TAny*. No destructor will be called when these objects are explicitly removed from the stack, either via PopAndDestroy() or when the stack implicitly performs cleanup upon leaving. (Note that it is fine for pointers to some objects, such as T-class objects, to be pushed onto the Cleanup Stack as TAny*, because they do not have destructors.) For this reason, remember to derive all C-classes from CBase.

Dangling pointers are easily created by forgetting to set pointers to NULL when explicitly deleting their corresponding objects. It is important to do this even if the next line of code allocates a new value, because the allocation itself may leave. One exception to this rule is in destructors, as member data pointers will fall out of scope as their class instance is destroyed.

Constructors and destructors should not call leaving functions. Doing this compromises the failsafe memory management measures offered by two-phase construction. Therefore, never call in a C++ constructor or destructor a function that can leave.

Virtual functions should not appear in constructors and destructors. The intention of a virtual function is to provide transparent access to its most derived implementation. This polymorphism feature is not available in constructors and destructors because the derived class will not exist at this time. In other words, the constructor of base class A does not know that it is actually creating a derived class B, and therefore a "virtual" function call within the constructor will only call class A's implementation.

Explicitly deleting an item that has already been placed on the Cleanup Stack is a mistake. By placing an item on the Cleanup Stack, you are relinquishing control of that item. By explicitly deleting the item, the Cleanup Stack is left with a dangling pointer to invalid memory梚ts subsequent attempt to delete this memory will cause an access violation.

Developers often forget to adhere to function naming standards梚n particular, make sure any functions that can leave have a trailing "L". (Symbian has developed a simple tool called Leavescan to check this for you梩his tool will be covered in the Testing section.)

Do not export inline functions, as this causes problems for dependent components at link time. Inline functions should be declared inline and an implementation should be provided in a separate .inl file.

Some of the application objects in a UI application梖or example, the CAknApplication-derived object梐re created before the Cleanup Stack. If a leave occurs before the Cleanup Stack is created, then the application will crash.

Developers often forget that their applications may eventually be ported to another language, and restrict descriptor sizes. Make sure that any descriptors that hold user-visible text have space to expand when localized, and that any controls that use such text can resize to fit.

Do not ignore compiler warnings. Although your application may still run, warnings often illustrate instances of bad coding practices.


创建或者修改应用程序svg图标的脚本在.mk文件中,一般叫“Icons_scalable_dc.mk”

CFbsBitmap 的 load() 有些时候不好用,比如总是返回错误代码-12。
此时可以换用:
iEikonEnv->CreateBitmapL() 或者
CEikonEnv::Static()->CreateBitmapL()

symbian发生错误会返回错误代码,代码查询网址:
http://wiki.forum.nokia.com/index.php/Symbian_OS_Error_Codes

讲授symbian字符串format的网址:
http://developer.symbian.org/wiki/index.php/Format_Strings

symbian 9 之后出于安全性考虑,引入了Capabilities的概念。比如应用程序需要接入网络,那么该应用程序必须“capability NetworkServices is required”。
如果应用程序只具备 read user data 的 capability 却发出了连接网络请求,那么程序可能会退出。
如果没有注意到权限的问题,可能会把程序因没有相关权限而意外退出的错误当bug来调试。结果当然很惨。
另外模拟器的权限很宽松(或许模拟器上就没有权限的限制,没有考证),这会造成程序在模拟器上运行正常,而在设备上无法正常运行,甚至意外退出。这是模拟器与设备的又一个差异。
应用程序权限设定方法如下:
在.mmp文件中键入如下行:
CAPABILITY ReadUserData WriteUserData NetworkServices
那么程序将具备读写用户数据和访问网络的能力。有些更大的权限需要到 www.symbiansigned.com 去申请。
另外,修改权限后,往往还要象征性地修改一下某个.cpp文件,重新编译,权限才会生效。

如果一个view因为需要接收键盘消息而AddToStackL(),在delete这个view前,应现将其RemoveFromStack()。否则可能发生崩溃。

symbian键盘编码
TKeyEvent中iCode与iScanCode的区别:
iScancode是扫描码, 需要经过前端处理器FEP处理过才能变成可识别的按键, 还是要用iCode处理
iScanCode保存的是键被按下或弹起的值,iCode保存的是一次完整按键事件对应的值.
另外键盘数字1,2...的iCode值我没有找到定义。郁闷。

handleCommand()与offerKeyEvent()的区别:
offerKeyEvent()处理所有来自键盘的消息。
handleCommand()将某些按键比如CBA的键盘消息转换成.hrh文件中定义的命令来处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值