将 TCHAR.H 数据类型用于 _MBCS 代码
定义清单常量 _MBCS
后,给定的一般文本例程会映射到以下其中一种例程中:
可恰当处理多字节字节、字符和字符串的 SBCS 例程。 在这种情况下,字符串参数类型应为
char*
。 例如,_tprintf
映射到printf
;printf
的字符串参数类型为char*
。 如果将_TCHAR
一般文本数据类型用于字符串类型,printf
的形参和实参类型将匹配,因为_TCHAR*
映射到char*
。MBCS 专用例程。 在这种情况下,字符串参数类型应为
unsigned char*
。 例如,_tcsrev
映射到_mbsrev
,这应该并且会返回的类型为unsigned char*
的字符串。 如果将_TCHAR
一般文本数据类型用于字符串类型,则会出现潜在的类型冲突,因为_TCHAR
映射到类型char
。
以下是防止此类型冲突(以及可能导致的 C 编译器警告或 C++ 编译器错误)的三个解决方案:
使用默认行为。 tchar.h 为运行时库中的例程提供一般文本例程原型,如下例所示。
char * _tcsrev(char *);
默认情况下,
_tcsrev
的原型通过 Libc.lib 中的 thunk 映射到_mbsrev
。 这将_mbsrev
传入参数和传出返回值的类型从_TCHAR*
(即char *
)更改为unsigned char *
。 这种方法可以确保在使用_TCHAR
时进行类型匹配,但该过程由于函数调用产生系统开销而相对较慢。通过在代码中包含以下预处理器语句来使用函数内联。
#define _USE_INLINING
此方法会导致 tchar.h 中提供的内联函数 thunk 将一般文本例程直接映射到相应的 MBCS 例程。 摘自 tchar.h 的以下代码提供了一个如何完成此操作的示例。
__inline char *_tcsrev(char *_s1) {return (char *)_mbsrev((unsigned char *)_s1);}
如果可以使用内联,这是最好的解决方案,因为它保证了类型匹配,并且不会产生额外的时间成本。
通过在代码中包含以下预处理器语句来使用“直接映射”。
#define _MB_MAP_DIRECT
如果不想使用默认行为或无法使用内联,则此方法提供了一种快速替代方法。 它使一般文本例程由宏直接映射到例程的 MBCS 版本,如以下 tchar.h 中的示例所示。
#define _tcschr _mbschr
在采用此方法时,必须小心以确保将适当的数据类型用于字符串参数和字符串返回值。 可以使用类型强制转换来确保类型匹配正确,也可以使用
_TXCHAR
一般文本数据类型。_TXCHAR
映射到 SBCS 代码中的类型char
,但映射到 MBCS 代码中的类型unsigned char
。 若要详细了解一般文本宏,请参阅运行时库参考中的一般文本映射。