疯狂的wchar_t

疯狂的wchar_t
PS: 我还是改个标题,不改怕被高手们骂死。

去年的这个时候当我决定把所有渲染和支持代码都向d3d10转移的时候,就准备搞定以后多语言的问题,于是义无反顾的选择了unicode。unicode处理中文字符串时候方便多了----至少在windows下是如此。
基于这个出发点,我的xml解析器直接处理的就是unicode文本,而不是常见的utf-8。(注,用记事本保存成unicode编码而不是utf-8,见附图,2008-12-10注)一切都很美好,知道我离开windows。上个礼拜,我需要把程序移植到linux下。在编译完程序后,xml加载器首先就了。gdb跟踪进去发现,竟然我取到的一个字符是负数,当时差点没晕倒。想了好长时间没想明白。楞了一个下午才反应过来sizeof(wchar_t) != 2 .....。除了xml文件,我的文件打包器的name成员是wchar_t。意味着我在windows下打包的文件时候在linux下一定会出问题。
考察了很久,猛然发现gcc有个option叫-fshort_wchar。 激动之,赶快加一个,make clean && make。---结果还是挂! 又让我郁闷了好久,继续gdb。发现wcslen(str)竟然短一半----原来glibc里的wchar_t还是4个字节。看来要使用-fshort_wchar还必须要编译glibc。
没办法,只能判断wchar_t长短来处理了。目前我的做法是准备做一个template,根据sizeof(wchar_t)来选择使用哪个字符串,保存在文件里的字串通通按照ucs-2来处理。并在加载时候来进行ucs-2/ucs-4转换。不敢轻易下决策了。等想一阵再说。看来unicode也不省心啊,家家都有本难念的经。

注:ucs分ucs2和ucs4,就是16bit和32bit的。utf8和utf16/utf32则是编码方式。utf8的anscii码基本和ansi一样。可以使用libiconv来进行各种编码方式之间转化。 编译器里的unicode通常是ucs-2-internal和ucs-4-internal。

附:目前我处理带wchar_t需要保存的结构体。

struct sCDDataEntryItem
{
public:
int m_StartAddr; /*long 4 - byte : FileStartAt */
xcd_data_type m_DataType;
int m_DataCompressedSize;/*long 4 - byte : PackedSize */
int m_DataSize; /*long 4 - byte : FileSize-Without packed */

int m_CompressedRate; /**/
int m_Reserved ; /*long 4 - byte : Reserved */

protected:
unsigned short m_utf16Name[128];

public:

virtual wchar_t* getDataName() = 0;
virtual void ValidateName() = 0;
virtual void SetDataName(const wchar_t* name) = 0;

public:
sCDDataEntryItem()
{
m_StartAddr = 0; /*long 4 - byte : FileStartAt */
m_DataType = xcddt_common;
m_DataCompressedSize = 0;/*long 4 - byte : PackedSize */
m_DataSize = 0; /*long 4 - byte : FileSize-Without packed */

m_CompressedRate = XCOMDOC_NOCOMPRESS; /**/
m_Reserved = 0 ; /*long 4 - byte : Reserved */
memset(m_utf16Name,0,sizeof(unsigned short)*128); /*char 128 - byte : File Name(Readable) */
}
};


template <int UCSTYPE> class T_CDDataEntryItemImp : public sCDDataEntryItem
{
};

template <> class T_CDDataEntryItemImp<2> : public sCDDataEntryItem
{
public:
wchar_t* getDataName()
{
return (wchar_t*)m_utf16Name;
}
void ValidateName()
{

}
void SetDataName(const wchar_t* name)
{
wcscpy( (wchar_t*)m_utf16Name,name);
}
};

template <> class T_CDDataEntryItemImp<4> : public sCDDataEntryItem
{
unsigned int m_ucs4DataName[128];
public:
wchar_t* getDataName()
{
if(sizeof(wchar_t) == 4)
return (wchar_t*)m_ucs4DataName;
}
void ValidateName()
{
XEvol_UCS2ToUCS4(m_utf16Name , m_ucs4DataName,128,128);
}

void SetDataName(const wchar_t* name)
{
wcscpy( (wchar_t*)m_ucs4DataName,name);
XEvol_UCS4ToUCS2(m_ucs4DataName , m_utf16Name ,128,128);

}

T_CDDataEntryItemImp()
{
memset(m_ucs4DataName , 0, sizeof(wchar_t) * 128);
}
};

typedef T_CDDataEntryItemImp<sizeof(wchar_t)> CDDataEntryItemImp;

疯狂的wchar_t

你可能感兴趣的:(char)