原本非UNICODE定义基于 char 类型,UNICODE定义基于 wchar_t 类型, Windows 在winnt.h中分别定义两个宏来代表这两种类型,
typedef char CHAR;
#ifndef _MAC typedef wchar_t WCHAR; // wc, 16-bit UNICODE character #else // some Macintosh compilers don't define wchar_t in a convenient location, or define it as a char typedef unsigned short WCHAR; // wc, 16-bit UNICODE character #endif
然后基于以上定义定义了一系列 TCHAR 宏,这样,可以让你的程序轻松地在 UNICODE 及 非 UNICODE环境之间移植,你只要使用 TCHAR相关的宏定义
在定义 wcs(wide char string 缩写) 常量时,需要使用L 前缀的字符串常量,如。
wchar_t mywstring = L "my wide char string";Windows 也提供了相应的封装宏定义 __T。
#ifdef UNICODE #define __T(x) L ## x ... #else #define __T(x) x ... #endif
/* Generic text macros to be used with string literals and character constants. Will also allow symbolic constants that resolve to same. */ #define _T(x) __T(x) #define _TEXT(x) __T(x)
#ifdef UNICODE 。。。略 /* String functions */ #define _tcscat wcscat #define _tcschr wcschr #define _tcscpy wcscpy #define _tcscspn wcscspn #define _tcslen wcslen #define _tcsncat wcsncat #define _tcsncpy wcsncpy #define _tcspbrk wcspbrk #define _tcsrchr wcsrchr #define _tcsspn wcsspn #define _tcsstr wcsstr #define _tcstok wcstok #define _tcsdup _wcsdup #define _tcsnset _wcsnset #define _tcsrev _wcsrev #define _tcsset _wcsset #define _tcscmp wcscmp #define _tcsicmp _wcsicmp #define _tcsnccmp wcsncmp #define _tcsncmp wcsncmp #define _tcsncicmp _wcsnicmp #define _tcsnicmp _wcsnicmp #define _tcscoll wcscoll #define _tcsicoll _wcsicoll #define _tcsnccoll _wcsncoll #define _tcsncoll _wcsncoll #define _tcsncicoll _wcsnicoll #define _tcsnicoll _wcsnicoll。。。略
#else /* ndef _UNICODE */ 。。。略 #define _tcscat strcat #define _tcscpy strcpy #define _tcsdup _strdup #define _tcslen strlen 。。。略 #ifdef _MBCS 。。。略 #define _tcschr _mbschr #define _tcscspn _mbscspn #define _tcsncat _mbsnbcat #define _tcsncpy _mbsnbcpy #define _tcspbrk _mbspbrk #define _tcsrchr _mbsrchr #define _tcsspn _mbsspn #define _tcsstr _mbsstr #define _tcstok _mbstok #define _tcsnset _mbsnbset #define _tcsrev _mbsrev #define _tcsset _mbsset #define _tcscmp _mbscmp #define _tcsicmp _mbsicmp #define _tcsnccmp _mbsncmp #define _tcsncmp _mbsnbcmp #define _tcsncicmp _mbsnicmp #define _tcsnicmp _mbsnbicmp 。。。略 #else /* !_MBCS */ 。。。略 #define _tcschr strchr #define _tcscspn strcspn #define _tcsncat strncat #define _tcsncpy strncpy #define _tcspbrk strpbrk #define _tcsrchr strrchr #define _tcsspn strspn #define _tcsstr strstr #define _tcstok strtok #define _tcsnset _strnset #define _tcsrev _strrev #define _tcsset _strset #define _tcscmp strcmp #define _tcsicmp _stricmp #define _tcsnccmp strncmp #define _tcsncmp strncmp #define _tcsncicmp _strnicmp #define _tcsnicmp _strnicmp 。。。略 #endif #endif
可以注意到 ,_strnicmp 在linux 中对应 strncasecmp,而 _wcsnicmp 在linux中是wcsncasecmp,但我没有在android NDK中找到相应功能函数,听说已经在libc中实现,但没有声明。
对于打开文件操作,如果文件名是以 UNICODE 格式存储的,在 MSVC2005之前使用 _tfopen 这个宏;在MSVC 2005 出现之后,你可以在第二个参数中使用 “ccs:UNICODE”来指定,如。FILE *fp = fopen(FILENAME, "rb,ccs=UNICODE");linux可能早已支持这种参数形式,可以参考linux man:fopen(3).如果没有指定ccs,linux将以你使用的第一个文件操作函数是 UNICODE的还是 非UNICODE 的来决定。(,ccs=string
The given string is taken as the name of a coded character set and the stream is marked as wide-oriented. Thereafter, internal conversion functionsconvert I/O to and from the character setstring. If the,ccs=string syntax is not specified, then the wide-orientation of the stream isdetermined by the first file operation. If that operation is a wide-character operation, the stream is marked wide-oriented, and functions to convert to thecoded character set are loaded.
)