« 基于垃圾回收的资源管理 | 返回首页 | 有的源码是不值得现在再去读的 »

Unicode vs Multibyte

我们的引擎的最初设计是 unicode 的,后来决定同时支持 unicode 和 multibyte 。所以我在 jamfile 里设置了一个叫做 unicode 的 feature 可以开关,这样我就可以得到两个版本。

但是,全部使用 unicode 又不太现实,有些系统提供的东西的接口就没有 unicode 版本,例如 fx 脚本。那么我们必须在 unicode 版本中又用回某些模块的 multibyte 版本。况且我们的引擎是跨平台的,不是所有的平台都像 Windows 这样对 unicode 支持的很好。管理两个版本本来就是一件非常麻烦的事情。

我们的引擎是二进制跨平台的,并且通过二进制模块耦合。这让我们切换单个模块的不同版本相对简单。经过测试,单独调试一个模块时,让其它模块都跑在 Release 版本下丝毫没有问题。所以我开始想着混合 unicode 和 multibyte 的版本的问题。

经过这几天考察,实际上,对于文字处理,大部分涉及模块,都只是将 string 传递来去,并不关心 string 的内容,也不会做复杂的操作。也就是说,大部分模块是没有必要在这个问题上分版本的。而真正涉及版本区别的,一种是引擎跟 OS 的接口。即去拿 A 结尾的 API 还是 W 结尾的 API 。这一点,完全可以运行时区分开。而且获取 OS 的 api 地址,只在初始化时做一次,根本没有性能损耗。

另一种是真正的 string 管理类,那么我们写两份放在同一模块里好了。在获取模块接口的时候根据实际情况构造寻要的一份即可。模块和模块之间的连接都是在启动的时候完成,它们可以正确的拿到需要的版本。

这次这个改动,代码变动量还是很大的。幸亏有一大堆的测试代码在那里可以跑,不然要改的心惊肉跳了。改动完毕后,控制 UNICODE 的宏将只对引擎使用者有用,并且仅仅改动的是引擎接口的描述。使用引擎的人将可以更灵活的作出选择了 :)


补遗: 这篇 blog 名字起的不好,这主要受 VC 对 unicode 工程的预定义宏 _UNICODE 的影响。这里特指 unicode-16 ,所以标题应该将 unicode 改做 widchar 。 事后反思了一下,觉得 Multibyte 足够用了,但是用 ANSI 字符串当是不妥。所以以 UTF-8 最为方便。

Comments

跨平台最好使用UTF8编码。
在Unix平台上,从数据库到应用软件到命令,utf8编码都得到了很好的支持。

unicode的好处能想到一点的是在文本编辑的时候不至于出现半个汉字之类的情况,其他的好处没想到。
问题是相对于大量需要转换unicode/非unicode的工作,这点点好处实在代价太高,毕竟很多地方还是需要用到非unicode。如果全世界都是unicode或者都是非unicode那是最方便了,象现在这种两边不着的情况还不如不用unicode

lua 的 string 是 0 安全的。lua state 有长度信息标识字符串。所以不会因为 0 打断。

这些文档中写的很清楚,请仔细阅读。

请教一下,如何使用C函数,将Unicode字符返回给lua,下面是做的一个扩展,但如果字串中包含ASCII码,因为会产生"\00"所以字符串给截断了,请问有何种方法可以解决。谢谢
static int l_mbstowcs (lua_State *L) {
int i;
luaL_Buffer b;
const char *s = luaL_checkstring(L, 1);
wchar_t *wc;

setlocale(LC_ALL, "");
i = strlen(s) * 2;

luaL_buffinit(L, &b);
wc = new wchar_t[i];
mbstowcs(wc, s, i);
luaL_addlstring (&b, (const char*)wc, i / 2);

delete [] wc;
luaL_pushresult(&b);

return 1;
}

UTF-8不错

lua 是 0 安全的 string 所以无所谓是否 unicode. 关于 lua 对 unicode 支持的问题,总是在 lua maillist 里有人提起,官方有多次解释, 可以去翻档案。

我也曾在我的blog中发泄,C++和unicode的粘合性很差,并不如java/C#这些基于虚拟机的语言那样天生就支持unicode。微软那帮混蛋把DXUT框架搞成只支持,结果害得我只能先把DXUT编成DLL,再在我的代码中使用。当然我也曾想写个工具,把
wchar全转为tchar,但是对于向D3DADAPTER_IDENTIFIER9 这种结构
本身里面是用的是multibyte字符。那么这种转换就涉及到编译器拉,也许可以通过template能解决。

最近向用lua来驱动DXUT中UI部分,可惜lua不支持unicode,一直纳闷中。

"不是所有的平台都像 Windows 这样对 unicode 支持的很好" 我到不太赞同这个观点。

是用TCHAR的方式吗?如果是的话可以试试用OLESTR,据说是跨平台的,COM本质论里面提到的垫片设计也不错。

unicode 没有任何好处?没有好处就没有存在的必要了 :D

你说的Unicode没有任何好处,是说你当前这个项目吧?
unicode特指那个utf-16么?

我想,如果只把字符串用于要给用户显示的部分。而配置、数据交换都用二进制的办法,不用XML,实际上用到的字符串是非常非常少的。
明确了这个前提,完全可以在内部进行UTF-16 到 UTF-8的转换,根本不存在性能问题。

今天刚看到消息,天下2要内测了,前几天天天加班,今天才知道消息,看来内测帐号很难搞到

若这样的话,听起来用UTF-8不错,既是multibyte,又可以方便转化成2字节的unicode

说实话,我个人并没有发现UNICODE的任何好处,我的程序里Multibyte可以处理任何的事情,感觉没必要使用UNICODE。

Post a comment

非这个主题相关的留言请到:留言本