技术宅的结界

 找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 156|回复: 3
收起左侧

【VB6】把BSTR和ANSI/UNICODE/UNICODE-BE/UTF8字符串互相转换

[复制链接]

39

主题

215

帖子

7821

积分

用户组: 管理员

UID
77
精华
14
威望
144 点
宅币
7090 个
贡献
158 次
宅之契约
0 份
在线时间
156 小时
注册时间
2014-2-22
发表于 2021-9-3 15:28:19 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有帐号?立即注册→加入我们

x
首先说明:ANSIUNICODE、UNICODE-BE(UNICODE BIG ENDIAN)的名称可能有歧义,以上名称来自WINDOWS记事本“另存为”对话框的【编码选择】处。

BSTR就是VB的STRING字符串,它本质上是UNICODE字符串。但讽刺的是,VB的自带控件竟然都不支持UNICODE。比如你想在中文系统上用VB自带控件(比如LABEL和TEXTBOX)正确显示德语的变音字母,是不可能的。要做的这点,必须用API自行创建控件。

ANSI字符串是最常见的,等同于C语言里的CHAR[],它的格式可以简单理解为“英文字符1字节+非英文字符2字节”。它的缺点在于非英文字符的编码有N种方法,比如简体中文WINDOWS系统的汉字编码是GBK(兼容GB2312),繁体中文WINDOWS系统的汉字编码是BIG5。如果在繁体中文WINDOWS系统上保存一个ANSI格式文本文件放到简体中文WINDOWS系统上打开就会显示为乱码,反之亦然。如果你的程序用了A版本的API,比如【MessageBoxA(0,"字符串",0,0)】,那么在非简体中文WINDOWS系统上看到的弹框将会是乱码;如果你的程序用的是W版本的API,比如【MessageBoxW(0,L"字符串",0,0)】,那么在非简体中文WINDOWS系统上看到的弹框则是正常的。

UNICODE字符串等同于C语言里的WCHAR[],所有字符就一律2个字节。该编码全球通用,不受地区和系统的影响。但如果字符串主要由英文字符组成时,会造成大量空间浪费。比如ABCD的ANSI编码是\x41\x42\x43\x44,但UNICODE编码则是\x41\x0\x42\x0\x43\x0\x44\x0。

UNICODE-BE字符串就是把UNICODE字符串的2个字节的位置调换了一下。比如某个字符的UNICODE编码是0xAA55,那么UNICODE-BE的编码就是0x55AA。该编码全球通用,不受地区和系统的影响。

综合ANSI和UNICODE的优缺点,于是就有了UTF8。对于纯英文字符,UTF8和ANSI是兼容的;对于非英文字符,UTF8有一套固定编码方法。该编码全球通用,不受地区和系统的影响。UTF8的缺点是一个中文字符的长度可能高达3字节甚至4字节。

使用MultiByteToWideChar和WideCharToMultiByte能让VB字符串(BSTR)和其它字符串相互转换。

以下是测试(把代码复制并保存为FRM文件即可运行):
游客,如果您要查看本帖隐藏内容请回复
回复

使用道具 举报

1087

主题

2602

帖子

7万

积分

用户组: 管理员

一只技术宅

UID
1
精华
234
威望
472 点
宅币
21255 个
贡献
45931 次
宅之契约
0 份
在线时间
2042 小时
注册时间
2014-1-26
发表于 2021-9-4 19:46:34 | 显示全部楼层
其实你所说的“UNICODE”是Win32编程里的“UNICODE宏”的概念,需要和Unicode编码形式的概念区分开。

Unicode使用32位整数存储每个字符,比如ABCD其实是41 00 00 00 42 00 00 00 43 00 00 00 44 00 00 00,看起来非常占空间,但它能表达的字符种类非常多,其中还包含了相当多的数量的Emoji表情字符等。

Win32编程的“UNICODE”其实使用的是UTF-16编码。其和UTF-8一样,是Unicode的压缩形式。通过判断高位的Bit组合来决定后续字节是否与当前字节共同组合为一个字符。

UTF-8、UTF-16都是Unicode的压缩形式,其压缩解压的算法十分简单,参考这个帖子可以不借助API进行其中的互转:10972

也可以参考这个更加早期的帖子:1676

顺带一提,VB6自带“StrConv”函数,可以进行字符串编码转换,和MultiByteToWideChar、WideCharToMultiByte的功能相同。

39

主题

215

帖子

7821

积分

用户组: 管理员

UID
77
精华
14
威望
144 点
宅币
7090 个
贡献
158 次
宅之契约
0 份
在线时间
156 小时
注册时间
2014-2-22
 楼主| 发表于 2021-9-6 22:10:47 | 显示全部楼层
0xAA55 发表于 2021-9-4 19:46
其实你所说的“UNICODE”是Win32编程里的“UNICODE宏”的概念,需要和Unicode编码形式的概念区分开。

Unic ...

StrConv不好使,只能和UNICODE互相转换。

但是BSTR和UNICODE互相转换可以直接使用“等号”实现。

0

主题

2

帖子

32

积分

用户组: 初·技术宅

UID
5597
精华
0
威望
2 点
宅币
26 个
贡献
0 次
宅之契约
0 份
在线时间
3 小时
注册时间
2020-2-9
发表于 7 天前 | 显示全部楼层
谢谢分享,学习了

本版积分规则

QQ|申请友链||Archiver|手机版|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2021-9-18 16:16 , Processed in 0.037685 second(s), 30 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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