前几日,此文章写到一半的时候,按保存键,然后发表,发现竟是空白。进入编辑模式后,回滚也没有效果,搞得兴致全无,我对csdn的blog的编辑器印象分大跌。闲言少叙,书说正题。

1. Symbian OS 中的exe文件
和Windows系统一样,Symbian OS也是用exe做为其可执行程序的扩展名。但是与Windows exe文件的PE结构不同,在ARM平台上的Symbian exe用的是一种叫做e32Image的文件结构。得出这样一个判断的理由是:在Symbian的build系统中,最后一步需要调用elf2e32,其实就是做一个文件结构的转换,将elf结构转化为e32结构。另外提一句,winscw是Symbian支持的一种build target平台,它的作用是方便程序员在windows系统上利用模拟器来进行调试,所以winscw平台下的exe就是windows支持的PE结构。
Symbian OS中的exe文件的内容可分为三个部分:代码区、只读静态数据区、可写静态数据区。与其他操作系统类似,如果系统上存在同一个exe的多个实例,代码区和只读静态数据区在内存中只有一份拷贝,多个实例(进程)共享同一份代码和静态数据;而可写静态区在每一个调用进程内都有一份拷贝。这种机制能够减少内存的开销。
Symbian只允许进程在它的主线程内调用一个exe。
2. Symbian OS 中的dll文件
2.1 两类dll文件
Symbian dll可以分为两类:共享库dll和多态dll。
a. 共享库dll
共享库实现了可能会被多个exe或dll调用的库代码。
和Windows中的静态dll相似, 共享库dll中实现了多个dll的导出函数。调用者通过dll提供者给出的头文件和lib文件,直接调用这些导入函数。如果某个exe静态连接了某些dll,在该exe载入时,会载入这些dll,如果这些dll又连接到了其他dll,又会递归的载入这些二次连接的dll。
b. 多态dll
多态dll即是封装了symbian ecom抽象接口类的dll。
它可以以dll为扩展名,但是通常会使用更能够表现该dll特性的扩展名。.app表示应用程序,.fep表示前端处理器,而.mdl表示的是一个识别器。
它通常只有单一的入口,通过这个gate函数实例化具体的实现类。
c. 共享库dll和多态dll的区别
| 共享库dll | 多态dll | |
| 可调用函数个数 | 多个 | 一个 |
| 被封装的实现代码 | 函数的集合或一个类的实现 | 一个抽象基类的实现 |
| 载入方式 | 静态载入:exe载入时相关dll载入 | 动态载入:RLibrary::Load()载入 |
| 扩展名 | dll | dll,app, fep,mlk |
2.2 TLS(Thread Local Storage)
注意:Symbian中的dll没有可写全局数据。一个Symbian进程可能要加载50个dll,一个dll的可写数据区至少是一个chunk(系统分配内存的最小单位),即4k个字节,那么总共就需要200k的内存空间,这对于手机上寸土必争的存储来说,显然是一个天文数字式的开销。那么,如果既想在dll中实现全局数据访问,又想让进程中的多个线程维护自己的全局数据拷贝,从而不会引起冲突,怎么办呢?这就是TLS出现的原因。
要正确的使用TLS,需要做三件事:在dll的入口函数E32dll()中初始化TLS;在函数中使用TLS;在dll释放时,释放TLS
a. 初始化TLS
- E32dll()
- {
- ...
- case EDllThreadAttach:
- CExample *p = CExample::new();
- if(p)
- {
- Dll::SetTls(p);
- }
- break;
- ...
- }
b. 使用TLS
- foo()
- {
- ...
- CExample *p = dynamic_cast<CExample> (Dll:Tls());
- ...
- }
c. 释放TLS
- E32dll()
- {
- ...
- case: DllThreadDetach:
- CExample *p = dynamic_cast< CExample >Dll::Tls();
- if(p)
- {
- delete p;
- Dll::SetTls(NULL);
- }
- break;
- ...
- }
3. Symbian OS 中的ECOM机制
3.1 ECOM的架构
ECOM是指由客户调用端,ECOM抽象接口,ECOM框架,ECOM实现类构成的plugin dll的使用和实现机制。
ECOM的好处是:一对于用户来说,可以通过统一的接口动态的调用不同的实现,而不需要关心内部是如何判断和实例化实现类,对于用户来讲,简单;二是对于ECOM dll的开发人员来说,容易通过虚基类进行扩展,对开发人员来说,扩展性更强。
客户端:只需要使用抽象接口提供的头文件,连接ECOM.lib文件,抽象接口的多态dll。客户端调用factory函数,通过参数或UID指定接口的实现类,得到一个实现类的指针。另外,一般还有一个ListImplementationL()函数,该函数负责返回该抽象接口对应的所有的实现类。
ECOM抽象接口:主要分为两个部分:一部分是导出的工厂类方法及其实现,主要是通过RECOMSession实例化一个实现类,这部分函数提供给客户端调用;另一部分声明了一些纯虚虚函数,这部分函数提供给实现类继承。
ECOM框架:ECOM框架可以理解为操作系统对抽象基类和相应的ECOM插件进行注册,管理,和调用。对于应用程序开发人员来说,只需要知道通过RECOMSession调用相应的实现类,通过一个统一的导出函数ImplementationGroupProxy来实现类的实现的注册。
ECOM实现类:需要实现抽象接口类定义的虚函数,需要实现ImplementationGroupProxy用于注册,需要提供一个特别格式的、编译后的rss资源向ECOM框架注册。需要实现一般C函数的newL和constructL
下图为ECOM的各部分之间的关系
3.2 ECOM的调用端
3.3 ECOM接口的基类
3.4 ECOM接口的实现类
3.5 ECOM的框架的系统实现
本文探讨了Symbian OS中如何在DLL中处理线程附着(EDllThreadAttach)和分离(DllThreadDetach)事件,通过创建和删除CExample对象,并使用Dll::SetTls和Dll::Tls()进行线程局部存储。
3831





