在编译arm平台程序的时候,出现如下错误提示:
ERROR: Dll 'AppName[UID].APP' has initialised data. 或者: ERROR: Dll 'AppName[UID].APP' has uninitialised data. (扩展名APP的应用程序其实也是一个DLL。) 而在为模拟器编译的时候,这个问题不会出现。这曾经导致我在完成完整的设计,编码和调试后, 从这条错误信息的字面意思是什么也看不出来的。initialised 和 uninitialised都一样有问题。 大家知道在程序运行的时候,DLL只会被装载一次。在Windows平台,每个进程都有自己独立的DLL空间。也就是说,不同进程装载同一个DLL,互相之间是独立的。只有在一个进程内,才是共享的。但是S60平台的设计是所有进程都共享同一个DLL空间。这样的设计显然是出于节约内存的目的,是很有必要的。但是这样就带来一个问题,那就是DLL里不可以有可写的全局变量,否则就要造成混乱。A进程对变量的改写会直接影响到B进程,这是程序设计者所不愿意看到的。所以,S60平台的编译器就禁止了在DLL内申明可写全局变量。但是全局变量还是可以用的,只要加上const申明即可。 一般来说,在做DLL设计的时候,的确不鼓励使用可写全局变量。即使是windows平台,DLL的可写全局变量也会在不同模块之间带来问题。当遇到这个编译器错误的时候,应该设法修改设计,回避使用全局变量。 但是因为APP实际上也是DLL,这就导致连S60的主程序也不能使用可写的全局变量,这个在某些时候就成了问题,全局变量毕竟是一个重要的实现手段。对此,S60提供了线程局部存储(thread local storage)来解决问题。 tls样例代码: 设置 使用
补充:
可写静态数据 全局可写静态数据(Global Writeable Static Data,WSD)就是在整个进程的生命周期内都存在的预处理变量。有时候我们需要WSD定义变量给其他的文件使用。这种情况时常发生在将非Symbian操作系统环境的代码移植到Symbian系统中来的时候。
EKA1上的WSD 在Symbian系统版本6.1, 7.0, 7.0s, 8.0a, 8.1a的内核架构EKA1中,仅仅在EXE类型的程序中支持WSD。我们不能在DLL和APP中使用WSD,如果我们进行了这样的定义,编译器会报告"初始化数据" 错误信息。 在EKA1中,我们如果要使用WSD的话,有下面这些解决办法: (1), 使用本地线程存储(TLS,Thread Local Storage)。 在Symbian的FAQ和技术技巧里面有例子关于怎么用TLS来定义WSD。 EKA2上的WSD 在Symbian系统版本8.0b, 8.1b及其版本9以后的内核中,EXE和DLL都支持使用WSD。不过尽管如此,在DLL中使用WSD仍然需要作一些小的修改, 需要在MMP文件中添加如下宏定义: EPOCALLOWDLLDATA 不过,这是有代价的。当在EKA2上使用WSD的时候需要仔细考虑以下列出的情况: (1) EKA2的模拟器上仅仅允许有WSD的DLL被一个进程装载。(最近做的项目中就遇到了这个问题,一个有WSD的DLL被两个exe调用导致这个两个exe不能相互调转切换,提示feature (2) WSD数据块占用RAM空间 (3) 在ARMv5上块是一种有限的资源 (4) 一个进程中有WSD的DLL的数目是受限的。
|
[S60] ARM平台独有问题 Writable Static Data in DLLs
2007-07-08 16:59