TPckg的使用

来源:互联网 发布:金山软件开除员工 编辑:程序博客网 时间:2024/05/17 09:06

描述符是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 );

由于datapkg是绑定的,因此buf中的数据被正确地copydata中了,这样data中的两个数字就变成了12了。目的达成。

但事情总没那么简单。现在结构体换了:

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()函数硬复制数据的时候产生了位置上的偏差。

另外,还有一个问题。我们知道,描述符中不单单存储有放入描述符的数据,还存储了一些描述符的属性。比如还有lengthmaxLength,分别代表描述符中当前的数据长度和最大数据长度。系统在使用描述符数据的时候也会读取这两个变量来确定描述符中数据的属性。比如说,就算描述符对应的内存里有很多数据,但描述符的length属性为0,那还是无法通过描述符对象本身来使用描述符中的数据的(比如无法把数据写入文件)。这里也是这个问题,注意:

pkg.Copy( buf );

这里调用的是包描述符的Copy函数,也就是说这个函数只会影响pkglength属性,而pkg内的subBuflength属性在复制完成后仍然为0!!!

就是前面提到的这两个问题导致了无法正确复制和使用数据,那应该怎么做呢?经过研究,可以这样来写复制代码:

TPtrC8 ptr( buf.Left( 2 ) );         // 取出前两个存放数字的字节
pkg.Copy( ptr );                     //
由于是数字可以直接复制进包描述符
ptr.Set( buf.Mid( 2, 14 ) );         //
假设字符串的长度为14
data.subBuf.Copy( ptr );             //
调用的是subBufCopy函数

好了,整个的过程就是这样,还是有点tricky的,但在Symbian C++中,描述符机制确实封装了很多有用的操作,简化了(如果应用的熟练)很多问题,最重要的是增加了安全性(利用了OO的技术,比如封装了一些描述符属性,可以用作数据检查)!。在强调代码安全又没有提供强大异常机制(主要是因为异常的开销太大,手机受不了)Symbian C++中,提供这样安全的描述符是很有益的。

另外,描述符在Symbian C++API中被大量的应用,理解并且用好描述符无疑对开发是非常有好处的,但是描述符中的trap的确比较多,继续加油吧,嘿嘿。



From:http://jimmyloveyou.spaces.live.com/Blog/cns!CE2ED69C7A191BDD!364.entry