Symbian OS S60 3rd platform 入门导航

本文介绍了Symbian开发的基础知识,包括C++函数使用、资源管理、模拟器与机器的区别、DrawText崩溃解决、获取文件完整路径、使用CEikLabel、在Symbian中使用标准C库函数、限制使用STL、.mbm与.mbg文件生成、路径读取、与字体相关的库、应用类型、编译错误解决、调试快捷键、列表资源使用、资源更新、绘图、内存管理、函数命名、图标创建、CFbsBitmap使用问题、错误代码查询、字符串format、权限设置、view管理、键盘编码、handleCommand与offerKeyEvent区别等。
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文件中定义的命令来处理。

内容概要:本文围绕基于风光储能和需求响应的微电网日前经济调度问题,提出了一套完整的Python代码实现方案。研究综合考虑风能、光伏等可再生能源的出力不确定性、储能系统的动态充放电特性以及需求侧响应机制,构建了以最小化系统综合运行成本为目标的优化调度模型。该模型充分体现了对可再生能源的高效消纳、系统经济性提升供需平衡调控的能力,通过Python编程结合优化求解器实现了模型的求解仿真验证,为微电网能量管理系统的设计科研分析提供了可复现的技术路径实践参考。; 适合人群:具备一定Python编程基础和电力系统优化调度知识的科研人员、工程技术人员及高校电气工程、能源系统等相关专业的研究生。; 使用场景及目标:①应用于微电网、智能配电网及综合能源系统的科研建模仿真分析;②帮助读者深入理解含高比例可再生能源的电力系统日前调度建模方法、目标函数构造约束条件处理技巧;③为实际工程中实现低碳、经济、可靠的微电网运行提供算法支持决策依据。; 阅读建议:建议读者结合文档中的代码实例,系统学习优化模型的数学表达编程实现过程,重点关注变量定义、目标函数构建、系统约束(如功率平衡、储能动态、机组出力等)的编码实现,并尝试调整负荷、新能源出力等输入数据进行多场景仿真,以深入掌握微电网调度策略的灵敏度分析优化效果评估方法。
### Spring源码面试终结者:31道核心题,源码级拆解IOCAOP 这份资源不是“面试八股文&rdquo;,而是对Spring、Spring Boot核心原理的**源码级深度拆解**。网上面试题答案大多浮于表面,无法应对面试官的连环追问。我结合源码阅读和实战踩坑,整理了这份**近10万字的硬核指南**,系统梳理了大厂面试中最棘手的31道Spring核心题。 **【资源核心内容】** - **IOCDI王者解析**:深入BeanFactoryApplicationContext层级设计,对比三种依赖注入方式,并用图文拆解三级缓存解决循环依赖的源码流程。 - **AOP事务底层原理**:彻底讲透动态代理选择策略,深度分析@Transactional失效的10大经典场景及源码级解决方案。 - **Spring MVC自动装配**:从DispatcherServlet的9大组件到SpringBoot的SPI机制,理清自动配置的完整加载链路。 - **高频追问满分话术**:每道题配有“低分vs高分回答&rdquo;对比,帮你精准拿捏面试官想要的“源码级理解&rdquo;。 **【特色】** 拒绝罗列概念,每道题都从“核心考点&rdquo;出发,深入到AbstractApplicationContext、TransactionInterceptor等Spring源码,帮助你在理解设计思想的同时,具备手写简易IOC容器的能力。 **【适合谁看】** 备战阿里、字节、美团等大厂面试的Java开发;对Spring原理一知半解,想系统提升源码阅读能力的开发者;希望从“会用&rdquo;进阶到“懂原理&rdquo;的技术人。 希望这份整理能帮你构建完整的Spring知识体系,轻松应对面试官的灵魂追问!
代码下载链接: https://pan.quark.cn/s/a4b39357ea24 二进制补码、小数的补码及运算规则 一、补码的概念和原理 补码是一种普遍的概念,在计算机系统中,所有数值均采用补码形式进行表示(存储)。补码的核心特性在于:借助补码,能够将符号位其它位进行统一处理;同时,减法运算亦可转化为加法运算来执行。补码的构成方式是在原码的基础上进行适当调整,原码表示法在数值前增加了一位符号位(即最高位用作符号位):正数该位为 0,负数该位为 1(0存在两种形式:+0 和-0),其余位用于表示数值的大小。 二、补码的表示和转换 补码的表示形式可区分为两种:整数的补码和小数的补码。 整数的补码表示方式: 1. 正数的补码其原码相同(即自身) 2. 负数的补码通过原码取反,然后在最低位加 1,符号位保持不变 小数的补码表示方式: 1. 正小数的补码其原码一致 2. 负小数的补码通过原码取反,然后在最低位加 1,符号位维持不变 三、补码的运算规则 补码的运算规则可归纳为三种:加法、减法和乘法。 1. 加法运算规则: [X+Y]补 = [X]补 + [Y]补 2. 减法运算规则: [X-Y]补 = [X]补 - [Y]补 = [X]补 + [-Y]补 3. 乘法运算规则: [X*Y]补= [X]补×[Y]补,即乘数(被乘数)相乘的补码等于补码的相乘。 需要强调的是,进行乘法运算时必须执行符号扩展:Nbit 乘数 和 Nbit 被乘数 都需符号扩展到 2Nbit,之后再进行直接相乘。 四、小数 Fraction 的补码表示和运算规则 小数 Fraction 的补码表示方式: 最高位为符号位,小数点位于符号位之后,其后的第一位代表 1/2,再后一位代表1/4,再...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值