百度空间 | 百度首页 
 
查看文章
 
[S60] ARM平台独有问题 Writable Static Data in DLLs
2007-07-08 16:59
在编译arm平台程序的时候,出现如下错误提示:
ERROR: Dll 'AppName[UID].APP' has initialised data.
或者:
ERROR: Dll 'AppName[UID].APP' has uninitialised data.
(扩展名APP的应用程序其实也是一个DLL。)

而在为模拟器编译的时候,这个问题不会出现。这曾经导致我在完成完整的设计,编码和调试后,
被迫放弃原有设计。

从这条错误信息的字面意思是什么也看不出来的。
initialised 和 uninitialised都一样有问题。
其实真正的含义是Dll里存在可写的全局变量。

大家知道在程序运行的时候,DLL只会被装载一次。在Windows平台,每个进程都有自己独立的DLL空间。也就是说,不同进程装载同一个DLL,互相之间是独立的。只有在一个进程内,才是共享的。但是S60平台的设计是所有进程都共享同一个DLL空间。这样的设计显然是出于节约内存的目的,是很有必要的。但是这样就带来一个问题,那就是DLL里不可以有可写的全局变量,否则就要造成混乱。A进程对变量的改写会直接影响到B进程,这是程序设计者所不愿意看到的。所以,S60平台的编译器就禁止了在DLL内申明可写全局变量。但是全局变量还是可以用的,只要加上const申明即可。

一般来说,在做DLL设计的时候,的确不鼓励使用可写全局变量。即使是windows平台,DLL的可写全局变量也会在不同模块之间带来问题。当遇到这个编译器错误的时候,应该设法修改设计,回避使用全局变量。

但是因为APP实际上也是DLL,这就导致连S60的主程序也不能使用可写的全局变量,这个在某些时候就成了问题,全局变量毕竟是一个重要的实现手段。对此,S60提供了线程局部存储(
thread local storage)来解决问题。
TLS的关键是两个函数:
void Dll::SetTls(void*)和void* Dll::Tls()
SetTls用于将任意类型的指针保存到线程局部存储中,而Tls()则取出该指针。
指针指向在堆上分配的一块内存。一个线程只能有一个局部存储变量。所以,如果你有很多全局变量,就要定义一个结构,把所有的全局变量封装在其中。这是挺别扭的,不过S60 3rd据说就支持dll的可写全局变量了。

tls样例代码:

设置
GlobalData* p = new GlobalData();
if ( p )
{
   Dll::SetTls( p );
}

使用
GlobalData* p = (GlobalData*) Dll::Tls();





类别:手机开发 | 添加到搜藏 | 浏览() | 评论 (0)
 
最近读者:
 
网友评论:
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码: 请点击后输入四位验证码,字母不区分大小写
      

     

©2009 Baidu