找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1409|回复: 3

[分享] ARX 多版本自适应字符集操作

[复制链接]

已领礼包: 13个

财富等级: 恭喜发财

发表于 2016-9-19 09:05:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
    首先,介绍一个WINDOWS的字符集,WINDOWS所支持的字符集包括两种,多字节和宽字符(UNICODE),而在WIN2K及其以上内核中,都是使用宽字符来实现的,但也保留了多字节支持的API接口,这个实现的原理,其实是收到多字节后,把其转换为宽字符,再传下内核对象处理的。
还有一点需要说明,Mircosoft将COM从16位转换成32位时,规定了将需要字符串的方法只接受UNICODE字符串。

下面先介绍一下两个宏
运行时库头文件定义UNICODE环境的宏 UNICODE
Windows头文件定义UNICODE环境的宏 _UNICODE

Microsoft公司提供的C运行时库与ANSI标准C运行时库是一致的,而ANSI规定运行时库必须支持UNICODE和ANSI(多字节)字符串和字符,所以WINDOWS运行时库也是支持多字节和宽字符编码操作的两套接口的。
最典型的是 多字节接口:strlen,strcat,strcmp等,对应的宽字符接口:wcslen,wcscat,wcscmp等。

有了上面的基础,我们开始说到主题。

由于ARX环境是需要支持多个版本,而字符操作在ARX中是非常常见的,所以很近切的需要能解决既能在多字节环境编译又能在宽字符环境编译的代码。不用急,WINDOWS开发过程中也存在同样的问题的,所以,MICROSOFT是提供了解决方案的,关键就在TCHAR.H这个头文件中。

在TCHAR.H文件中,会根据_UNICODE宏是否定义来实现字符编码及其操作接口的自适应,如,在该文件中,对于CHAR的定义是这样的,当定义的_UNICODE宏是 typedef wchar_t TCHAR,当没有定义时 typedef char TCHAR,所以,当我们在定义字符串或字符时,只需要使用TCHAR来代替char,就能实现多字节与宽字符环境自适应的字符定义了。

定义后,我们关心的就是正确的给变量赋值了,在运行时库中,提供一个方法,当在某个字符串常量前加上大写L,则通知编译器,该字符串作为UNICODE字符串来编译,所以在TCHAR.H中也利用了这一点,来定义了随环境变化的通知编译器字符编码的机制。当定义了_UNICODE时,#define _TEXT(x) L##x,当没有定义时 #define _TEXT(x) x,这样只需要对每个常量字符串加上_TEXT()操作就可以自适应编译环境了。而在TCHAR.H中_TEXT又被定义成了更短,大名鼎鼎的_T了,所以,我们只需要对每个常量字符串加上_T()操作就可以自适应编译环境了。

另外一点,TCHAR.H中,也针对_UNICODE宏是否定义,实现了一套自适应编码环境的字符操作接口,所以建义在进行ARX编程时,如果需要多版本的支持,一定要使用TCHAR.H中定义的字符操用接口。

而且还需要说明的一点,MFC中的CString是随环境自适应的字符集,所以建义大家在编程过程中,尽量使用CString,而不是std::string。
最后把一常用需要注意的和代替的方法贴出来:
1.字符串类型尽量用CString
2.字符类型使用 TCHAR
3.字符串数组用 TCHAR[]
4.字符串指针用 TCHAR*
5.常量字符串指针用 const TCHAR*
6.字符串常量和字符常量加宏 _T
特别的:
1>CString::Format(_T("..."),...)//要加_T
2>LPTSTR 等等被多次嵌套定义过的宏尽量少用,用基础类型 const TCHAR*(或TCHAR*)替代;
3>为TCHAR*类型指针分配 N-1 个字符的空间: TCHAR* pbuffer = new TCHAR[ N*sizeof(TCHAR) ];
常用字符串函数,须使用支持Unicode/Ansi的宏函数替换前者:
Ansi字符串函数 Unicode/Ansi宏函数 功能说明
strcpy _tcscpy      字符串拷贝
strcat _tcscat      字符串连接
strlen _tcslen       求字符串长度
strcmp _tcscmp     字符串比较
atof _tcstod (注) 字符串转换为double
atoi _ttoi 字符串转换为int
注:上表中 _tcstod 和 atof用法不同,不能直接替换。
TCHAR与CString 互相转换
CString   str   =   _T("你好");  
char   s[50];  
s   =   (LPTSTR)(LPCTSTR)str;  
str   =   (LPCTSTR)(LPSTR)s;
附上OBJECTARX每个版本对应的字符集:
OBJECTARX2007及其以上都是UNICODE(宽字符)编码。
OBJECTARX2007以下都是ANSI(多字节)编码。

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 1304个

财富等级: 财源广进

发表于 2016-9-19 14:06:14 | 显示全部楼层
高手如云啊
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 112个

财富等级: 日进斗金

发表于 2016-9-21 10:43:42 | 显示全部楼层
学习了,谢谢楼主分享
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 344个

财富等级: 日进斗金

发表于 2016-9-21 22:08:32 | 显示全部楼层
学习了!
特别的第3条:3>为TCHAR*类型指针分配 N-1 个字符的空间: TCHAR* pbuffer = new TCHAR[ N*sizeof(TCHAR) ];
有误!
应为TCHAR* pbuffer = new TCHAR[N] TCHAR* pbuffer = (TCHAR*)malloc[ N*sizeof(TCHAR) ]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-5-26 01:37 , Processed in 0.178783 second(s), 34 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表