MultiByteToWideChar 和 WideCharToMultiByte 函数的第一个参数是 CodePage,代码页,CSDN 的解释是:Code page to use in performing the converison. 只是说,这个参数被用来执行转换,并没有说是目标字符的代码页,还是源字符的代码页,有点让人发晕。
MultiByteToWideChar 是要将多字节序列宽字符序列转化为宽字符。
当表示同一个含义,如“我是李志浩” 时,多字节字符序列和宽字符序列是两种不现的表现外在形式,内涵其实是等价的。 “我是李志浩” 的内码值(数学表示)是确定的,即它有唯一的 UNICODE 编码值(它不能被 ANSI 编码,因为 ANSI 是英文字符加特殊符号编码,不能表示中文; )。它还有唯一的 GBK 编码(这个编码系列从 gb2312 发展到 GBK 再发展到 GB18030,各代都做了两件事情:增加内码值,优化表示方式)。Windows 系统内部使用的是 UNICODE 编码。
宽字符序列 (wchar_t*) 即是 Unicode 字节序列,内码值序列,它是操作系统真正处理的字节序列。有不同的表现形式的一个事物,操作系统最终处理的必然是那个确定的事物:剔除了任何修饰,转化后的那个确定的事物!
多字节序列(char*) 就是对于一个确定的事物的修饰,转化后的东西:这句话“我是李志浩”用 UTF8 表示时,计算机能看到的是使用了 UTF8 技法转换成的很多个字节。使用 GB2312 表示时,计算机能看到的又是另外一个外貌的很多个字节。总之,使用不同的表示方法时,计算机看到的总是不同的字节序列。这也就是“多字节序列”的含义。
现在假设,给计算机输入一个使用 UTF8 编码的中文绝对路径 “D:/李志浩的工程/Test”,计算机想打开这个目录,就要搞清楚它的含义。那么问题来了,计算机收到了 “D:/李志浩的工程/Test”,但实际上计算机看到的是很多个字节的序列,为了让计算机懂这个序列是什么含义,它还需要知道如何去解析这个多字节序列。于是,我们就给了计算机一个黑板,上面写的是解析方法:
0xxxxxxx (00-7f)
110xxxxx 10xxxxxx (c0-df)(80-bf)
1110xxxx 10xxxxxx 10xxxxxx (e0-ef)(80-bf)(80-bf)
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx (f0-f7)(80-bf)(80-bf)(80-bf)
111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx (f8-fb)(80-bf)(80-bf)(80-bf)(80-bf)
1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx (fc-fd)(80-bf)(80-bf)(80-bf)(80-bf)(80-bf)
左边的是表现形式,用它去多字节序列中查找,解码,右边是 UNICODE 内码值,计算机的内部表示。于是计算机就可以将上面的多字节序列转换为宽字节序列, wchar_t* ,此时,它终于可以理解那个路径是啥了,可以处理。
上面提到的那个黑板,即是 codePage ,也就是这个多字节序列的编码方式。
WideCharToMultiByte 方法,从宽字节序列转为多字节序列,毫无疑问, WideChar 即是 Unicode 编码序列,即内码序列,计算机必然认识它,我们只需要告诉系统,需要转化成的目标序列的编码方式即可。也同样就是 codePag 这个参数。
所以,综上来看,MultiByteToWideChar 和 WideCharToMultiByte 的 codePage 参数,都是指多字节序列的编码方式的(前者为源,后者为目标)。