收藏
描述符是Symbian C++ 当中很有特色的东西。她是采用完全面向对象的思想构件的,使用她既可以处理字符串也可以处理二进制数据。描述符的设计体系是很“ 优雅” 的,但在你感受到她的优雅之前一定会经历一段曲折的极其不优雅的痛苦过程。呵呵,道路是曲折的,前途是光明的!这里记录一下我两天来使用包描述符类的经验,主要目的是防止自己忘记,呵呵。
由于项目的需要,我需要用一个结构体(或者结构体类)来存放一系列数据,为了能够操作这些数据(主要是内存操作),我必须把这个结构体同一个包描述符联系起来,由于很多内存操作函数都是在描述符基类中提供,因此与某个描述符建立联结后就可以用这些函数来操作对应的内存了。比如我可以这样做:
struct TData
{
TInt8 num;
TInt8 alsoANum ;
};
TData data;
TPckg <TData > pkg ( data ); // 或者 TPckgBuf <TData > pkg ( data );
这样的话就可以用一个包描述符来描述这个结构体了。其中TPckg 其实就是一个指向一块内存的指针,而TPckgBuf 是在栈上新开辟了一块内存,然后在其中存放data 数据的副本。这里值得注意的是这两个类的基类都为TDesC8 ,因此她们处理数据的单位都为单个字节。假如有一个TBuf8 ,其中存放了你需要的数据:
TBuf8<2> buf ;
buf.Append ( 1 );
buf.Append ( 2 );
然后你希望把这个TBuf8 里的数据对应的放到结构体data 里去,由于data 中没有方法,因此就必须用TPckg 中的方法来处理内存(这也是为什么要用包描述符)。可以这样做:
pkg.Copy ( buf );
由于data 和pkg 是绑定的,因此buf 中的数据被正确地copy 到data 中了,这样data 中的两个数字就变成了1 和2 了。目的达成。
但事情总没那么简单。现在结构体换了:
struct TData
{
TInt8 num;
TInt8 alsoANum ;
TBuf8<16> subBuf ;
};
TData data;
TPckg <TData > pkg ( data );
此时假设在另一个TBuf8 中(假定就是buf 中)已经存放了对应结构的数据,现在我打算把buf 中的数据复制到data 中,首先我先这样做:
pkg.Copy ( buf );
这样做似乎很有道理,把对应的内存copy 过去,貌似没什么不妥。但监测内存后发现,这样的复制是有问题的,内存中的数据没有被正确的复制。首先,当data 中不包含另外的描述符的时候,这样做一点问题也没有,就像刚才第一个例子里那样。问题肯定出在新加进结构体的subBuf 上。研究了包描述符pkg 的内存结构后发现,如果在结构体中放入一个描述符的话,在pkg 中会多出8 个字节,据说这多出来的8 个字节是为了描述包描述符中的子描述符的长度的。因此就是这多出来的8 个字节导致了在使用Copy() 函数硬复制数据的时候产生了位置上的偏差。
另外,还有一个问题。我们知道,描述符中不单单存储有放入描述符的数据,还存储了一些描述符的属性。比如还有length 和maxLength ,分别代表描述符中当前的数据长度和最大数据长度。系统在使用描述符数据的时候也会读取这两个变量来确定描述符中数据的属性。比如说,就算描述符对应的内存里有很多数据,但描述符的length 属性为0 ,那还是无法通过描述符对象本身来使用描述符中的数据的(比如无法把数据写入文件)。这里也是这个问题,注意:
pkg.Copy ( buf );
这里调用的是包描述符的Copy 函数,也就是说这个函数只会影响pkg 的length 属性,而pkg 内的subBuf 的length 属性在复制完成后仍然为0 !!!
就是前面提到的这两个问题导致了无法正确复制和使用数据,那应该怎么做呢?经过研究,可以这样来写复制代码:
TPtrC8 ptr ( buf.Left ( 2 ) ); // 取出前两个存放数字的字节
pkg.Copy ( ptr ); // 由于是数字可以直接复制进包描述符
ptr.Set ( buf.Mid ( 2, 14 ) ); // 假设字符串的长度为14
data.subBuf .Copy ( ptr ); // 调用的是subBuf 的Copy 函数
好了,整个的过程就是这样,还是有点tricky 的,但在Symbian C++ 中,描述符机制确实封装了很多有用的操作,简化了( 如果应用的熟练) 很多问题,最重要的是增加了安全性(利用了OO 的技术,比如封装了一些描述符属性,可以用作数据检查)!。在强调代码安全又没有提供强大异常机制( 主要是因为异常的开销太大,手机受不了) 的Symbian C++ 中,提供这样安全的描述符是很有益的。
另外,描述符在Symbian C++ 的API 中被大量的应用,理解并且用好描述符无疑对开发是非常有好处的,但是描述符中的trap 的确比较多,继续加油吧,嘿嘿。
From:http://jimmyloveyou.spaces.live.com/Blog/cns!CE2ED69C7A191BDD!364.entry
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/WTK870424/archive/2009/12/09/4973898.aspx