新闻中心

EEPW首页>嵌入式系统>设计应用> Win CE开发特性及忠告

Win CE开发特性及忠告

作者: 时间:2016-09-12 来源:网络 收藏

本文引用地址://m.amcfsurvey.com/article/201609/305178.htm

在Intel系列处理器上,你可以在一奇数内存地址储存任何变量或数组,不会导致任何致命的错误影响。但在H/PC上,这一点不一定能行 ? 你必须对大于一个字节的数据类型小心谨慎,包括定义为无符号短型(unsigned short) 的wchar_t。当你设法访问它们的时候,将它们置于奇地址会导致溢出。

编辑器经常在这些问题上提醒你。你无法管理堆栈变量地址,并且编辑器会检查确定这些地址与变量类型是否相匹配。同样,运行时间库必须保证从堆中分配的内存总是满足一个word边界 ,所以你一般不必担心那两点。但是,如果应用程序含有用memcpy()函数拷贝内存区域的代码,或者使用了某种类型的指针算术以确定内存地址,问题也许就出现了。考虑下面的例子:

int send_name (TCHAR * pszName)

{

char *p, *q;

int nLen=(_tcslen(pszName) + 1) * sizeof(TCHAR);

p=maloc(HEADER_SIZE + nLen);

if(p)

{

q = p + HEADER_SIZE;

_tcscpy((TCHAR*)q, pszName);

}

/* etc */

这段代码是从堆中分配内存并复制一个字符串,在字符串的开头留一个HEADER_SIZE的大小。假设UNICODE定义了,那么该字符串就是一个widechar字符串。如果HEADER_SIZE是一个偶数,这段代码就会正常工作,但如果HEADER_SIZE为奇数,这段代码就会出错,因为q指向的地址也将为奇数。

注意,当你在Intel系列处理器中的Windows CE仿真器上测试这段代码时,这个问题是不会发生的。

在这个例子中,只要确保HEADER_SIZE为偶数,你就可以避免问题的发生。然而,在某些情况下你也许不能这么做。例如,如果程序是从一台式PC输入数据,你也许不得不采用事先定义过的二进制格式,尽管它对H/PC不适合。在这种情况下,你必须采用函数,这些函数用字符指针控制字符串而不是TCHAR指针。如果你知道字符串的长度,就可以用memcpy()复制字符串。因此,采用逐个字节分析Unicode字符串的函数也许足以确定字符串在widechars中的长度。

在ANSI和Unicode字符串之间进行翻译

如果你的Windows CE应用程序接口于台式PC,也许你必须操作PC机中的ANSI字符串数据(例如,char字符串)。即使你在程序中只用到Unicode字符串,这都是事实。

你不能在Windows CE上处理一个ANSI字符串,因为没有操纵它们的库函数。最好的解决办法是将ANSI字符串转换成Unicode字符串用到H/PC上,然后再将Unicode字符串转换回ANSI字符串用到PC上。为了完成这些转换,可采用MultiByteToWideChar()和WideCharToMultiByte () Win32 API 函数。

对于Windows CE 1.0的字符串转换,劈开(hack)

在Windows CE 1.0 版本中,这些Win32API函数还没有完成。所以如果你想既要支持CE 1.0又能支持CE 2.0,就必须采用其它函数。将ANSI字符串转换成Unicode字符串可以用wsprintf(),其中第一个参数采用一widechar字符串,并且认识%S(大写),意思是一个字符串。由于没有wsscanf() 和 wsprintfA(),你必须想别的办法将Unicode字符串转换回ANSI字符串。由于Windows CE 1.0不在国家语言支持(NLS)中,你也许得求助于hack,如下所示:

/*

Definition / prototypes of conversion functions

Multi-Byte (ANSI) to WideChar (Unicode)

atow() converts from ANSI to widechar

wtoa() converts from widechar to ANSI

*/

#if ( _WIN32_WCE >= 101)

#define atow(strA, strW, lenW)

MultiByteToWidechar (CP_ACP, 0, strA, -1, strW, lenW)

#define wtoa(strW, strA, lenA)

WideCharToMutiByte (CP_ACP, 0, strW, -1, strA, lenA, NULL, NULL)

#else /* _WIN32_WCE >= 101)*/

/*

MultiByteToWideChar () and WideCharToMultiByte() not supported o-n Windows CE 1.0

*/

int atow(char *strA, wchar_t *strW, int lenW);

int wtoa(wchar_t *strW, char *strA, int lenA);

endif /* _WIN32_WCE >= 101*/

#if (_WIN32_WCE 101)

int atow(char *strA, wchar_t *strW, int lenW)

{

int len;

char *pA;

wchar_t *pW;

/*

Start with len=1, not len=0, as string length returned

must include null terminator, as in MultiByteToWideChar()

*/

for(pA=strA, pW=strW, len=1; lenW; pA++, pW++, lenW--, len++)

{

*pW = (lenW = =1) ? 0 : (wchar_t)( *pA);

if( ! (*pW))

break;

}

return len;

}

int wtoa(wxhar_t *strW, char *strA, int lenA)

{

int len;

char *pA;

wchar_t *pW;

/*

Start with len=1,not len=0, as string length returned

Must include null terminator, as in WideCharToMultiByte()

*/

for(pA=strA, pW=strW, len=1; lenA; pa++, pW++, lenA--, len++)

{

pA = (len==1)? 0 : (char)(pW);

if(!(*pA))

break;

}

return len;

}

#endif /*_WIN32_WCE101*/

这种适合于Windows CE 1.0的实现办法比使用wsprintf()函数要容易,因为使用wsprintf()函数更难以限制目标指针所指向的字符串的长度。

选择正确的字符串比较函数

如果你要分类Unicode标准字符串,你会有以下几个函数可供选择:

wcscmp(), wcsncmp(), wcsicmp(), 和wcsnicmp()

wcscoll(), wcsncoll(), wcsicoll(),和wcsnicoll()

CompareString()

第一类函数可用来对字符串进行比较,不参考当地(Locale)或外文字符。如果你永远不想支持外文,或者你仅仅想测试一下两个字符串的内容是否相同,这类函数非常好用。

第二类函数使用现有的当地设置(current locale settings)(系统设置,除非你在字符串比较函数之前调用了wsetlocale()函数)来比较两个字符串。这些函数也能正确分类外文字符。如果当地的字符C(C locale)被选定,这些函数与第一类函数就具有了相同的功能。



关键词:

评论


相关推荐

技术专区

关闭