symbian 描述符问题

一、_LIT宏
在讨论描述符之前,有必要来看下_LIT宏
可以用它引入一个字符串常量, 如_LIT(KText, "OK");
KText并不是描述符,而是TLiC类型,TLiC类的定义在<e32std.h>,3rd fp1 将其定义在<e32cmn.h>,其中有一个public变量,TUint iTypeLength; 表示字符串的长度
 
可以通过3种方式转换为描述符:隐式转换,使用operator()转换和使用operator&转换,《Series 60应用程序开发》P74讲到了,
在<e32std.inl>中可以看到的转换函数的定义
// Template class TLitC
// 使用operator&转换
template <TInt S>
inline const TDesC* TLitC<S>::operator&() const
 {return REINTERPRET_CAST(const TDesC*,this);}
// 使用operator()转换
template <TInt S>
inline const TDesC& TLitC<S>::operator()() const
 {return *operator&();}
// 以下两种是隐式转换
template <TInt S>
inline TLitC<S>::operator const TDesC&() const
 {return *operator&();}
template <TInt S>
inline TLitC<S>::operator const __TRefDesC() const
 {return *operator&();}
 
在<e32std.h>,3rd fp1 <e32cmn.h>中有下面几个常量,有时你会用到的
_LIT(KNullDesC,"");
_LIT8(KNullDesC8,"");
_LIT16(KNullDesC16,"");
 
另外很多人也许会用到 _L宏,因为比较方便,但很多书上说相比_LIT宏,它具有效率低和作用域相关问题,建议使用_LIT宏。
 
二、TDesC
在<e32des16.h>中,TDesC16类定义有:
private:
#if defined(__DESC_NO_BIT_FIELDS__)
 TUint iLength;
#else
 unsigned int iLength:28;
 unsigned int iType:4;
#endif
 __DECLARE_TEST;
 
这里不是太懂,
我们只看其中两个成员变量,iLength和iType。
1、iLength表示对象的长度, 可以通过成员函数Length()来获得,  Length()就是返回字符的个数?不一定,请看下面的代码,本人分三种情况进行分析。
_LIT(KFormat, "%d");
_LIT(KNEWLINE,"/n");
TInt ITemp;

// 先看下无汉字时的情况

_LIT8(KOkText8, "OK");
_LIT16(KOkText16, "OK");
 

//使用operator()转换,然后使用TDesC8::Length(); 得ITemp == 2
ITemp = KOkText8().Length();  
console->Printf(KFormat, ITemp);
console->Printf(KNEWLINE);
// ITemp == 2
ITemp = KOkText16().Length();
console->Printf(KFormat, ITemp);
console->Printf(KNEWLINE);
 
// 再来看下汉字的情况
_LIT8(KCnText8,   "中国"); 
_LIT16(KCnText16, "中国");
// 请注意这时ITemp == 4 而不是2
ITemp = KCnText8().Length();
console->Printf(KFormat, ITemp);
console->Printf(KNEWLINE);
// ITemp == 2   (但在3rd中 == 4)
ITemp = KCnText16().Length();
console->Printf(KFormat, ITemp);
console->Printf(KNEWLINE);
 

//最后看下有汉字时的另一种情况(这种情况有点复杂,因为牵涉到编码知识)

我们在编译器里写的代码(如上面)的编码默认是ANSI, 如果你在ANSI的编码输入汉字,那么他实际就是GBK的编码方式,还有一种我们可能要用到的编码UTF-8,如下代码
_LIT8(KText8, "中国");
来源:(http://blog.sina.com.cn/s/blog_4a774f1e010099f4.html) - symbian 描述符问题_Love_新浪博客
_LIT16Text16, "中国");

将其保存到Common.h头文件中,同时将其保存为UTF-8编码。
在cpp文件中有
// 请注意这时ITemp == 6 而不是4,更不是2, 原因有点复杂,但可以确定的是一个汉字返回的Length()是3
ITemp =  KText8().Length();
console->Printf(KFormat, ITemp);
console->Printf(KNEWLINE);

// ITemp == 2 (但在3rd中 == 6)
Temp =  KText16().Length();
console->Printf(KFormat, ITemp);
console->Printf(KNEWLINE);

 
2、iType感觉是用于区别具体派生类的类型, 本人试了下,iType的值为
0: HBufC 和 TBufC
1: TPtrC
3: TBuf
4: TPtr
 
所有描述符的基类是TDesC,该类实际上为一个抽象类,在symbian的头文件中,该对象的所有构造函数都为protected。因此你无法创建TDesC,也永远不会(应该说你不应该)出现如下的语句: TDesc des。但是symbian可能疏忽了,也比较程序容易出错的是,它没有屏蔽C++自动产生的拷贝构造函数。因此下面的语句没有任何编译警告:
extern TPtrC ptr; //TPtrC是TDesC的派生类
TDesC des = ptr; //调用默认的拷贝构造函数,造成slice切割
foo(des); //调用一个函数,需要const TDesC&参数,由于数据已被切割,结果无法预料。


它主要用于函数参数传递,作为函数参数时,不是const TDesC& des,就是const TDesC× des,

 
三、TBuf、TBufC
_LIT(KText, "123");
//  or TBuf<10> BufTemp = KText; (但在3rd中会报错,很奇怪)

TBuf<10> BufTemp(KText);
// 再看下面代码
TText cstr[3] = {'1', '2', '3'};
TBuf<10> BufTemp1(&cstr[0]);
TBuf<10> BufTemp2(cstr);
TBuf<10> BufTemp3= cstr;
TBuf<10> Buftemp4(BufTemp1);
上面的代码在编译的时候不会出问题,但在运行的时候在会报USER 11的越界错误,将TText cstr[3] = {'1', '2', '3'};改为TText cstr[3] = {'1', '2'};就可以了,这种错误有时很难发现,建议初始化TText变量时最好在最后加上'/0',即改为TText cstr[3] = {'1', '2','/0'};

 
四、TPtr、TPtrC
1、利用TBufC对其初始化

_LIT(KText, "123");

//  or TBufC<50> BufCTemp = KText; (但在3rd中会报错,很奇怪)

TBufC<50> BufCTemp(KText);


TPtr  ptr1 = BufCTemp.Des();
TPtr  ptr2(BufCTemp.Des());
//TPtr  ptr3(BufCTemp);  // 报错


TPtrC ptrC1 = BufCTemp;
TPtrC ptrC2(BufCTemp);

 

2、利用TBuf对其初始化

//TBuf<50> BufTemp = KText; //(但在3rd中会报错,很奇怪)

TBuf<50> BufTemp(KText);

//TPtr  ptr1 = BufCTemp.Des();// 报错
//TPtr  ptr2(BufCTemp.Des()); // 报错
//TPtr  ptr3(BufCTemp);       // 报错

TPtrC ptrC1 = BufTemp;
TPtrC ptrC2(BufTemp);

 

上面的报错原因你可以参考SDK文档

 

 

最后:字符串之间的转换
1、char 到 TBuf
char* aShortName="123";
TText16 a[20]; // or TUint16 a[20];
TInt i;
for (i =0; i<strlen(aShortName); i++)
{
  a[i] = aShortName[i];
}
a[i]='/0';
TBuf<20> bufShortName ;
bufShortName = a;
 
2、
 
to be continued。。。。。。。。。
 

你可能感兴趣的:(symbian 描述符问题)