在文章如何在vba中实现字符的Unicode编码与ANSI编码相互转换?中介绍了利用vba内置函数StrConv 实现字符的Unicode编码与ANSI编码的相互转换。
今天,介绍利用api函数WideCharToMultiByte和MultiByteToWideChar 实现字符的unicode编码和utf-8编码相互转换。
其中WideCharToMultiByte语法如下:
int WideCharToMultiByte( _In_ UINT CodePage, _In_ DWORD dwFlags, _In_ LPCWSTR lpWideCharStr, _In_ int cchWideChar, _Out_opt_ LPSTR lpMultiByteStr, _In_ int cbMultiByte, _In_opt_ LPCSTR lpDefaultChar, _Out_opt_ LPBOOL lpUsedDefaultChar );
其中参数codepage表示要以什么字符集进行转换,具体的值可以从Code Page Identifiers获取到。
一般的几个常用的值为Const CP_UTF8 = 65001(表示转换为UTF-8),Const CP_ACP = 0(标准转换为系统默认的ANSI编码)
dwFlags参数一般为0,lpWideCharStr参数指的指向要转换的字符串的指针,cchWideChar参数表示要转换的字符串的字符数,lpMultiByteStr参数为指向接收转换后的字节的缓存区的指针,cbMultiByte参数表示以字节为单位表示的lpMultiByteStr参数的缓存区的字节大小,如果cbMultiByte参数设置为0,则WideCharToMultiByte函数将返回实际转换后需要的字节数,lpDefaultChar参数和lpUsedDefaultChar参数一般设置为0。
类似的MultiByteToWideChar 参数的语法如下:
int MultiByteToWideChar( _In_ UINT CodePage, _In_ DWORD dwFlags, _In_ LPCSTR lpMultiByteStr, _In_ int cbMultiByte, _Out_opt_ LPWSTR lpWideCharStr, _In_ int cchWideChar );
其中参数codepage表示要以什么字符集进行转换,dwFlags参数一般为0,lpMultiByteStr参数表示指向待转换字符串的指针,cbMultiByte参数表示以字节为单位表示的lpMultiByteStr参数的字节大小。lpWideCharStr参数表示指向的转换后的结果字符串的指针,cchWideChar参数表示转换后的字符串的字符数,如果cchWideChar参数设置为0,则MultiByteToWideChar 函数将返回实际转换后的字符串的字符数。
根据以上的分析,可以使用如下的代码实现字符的Unicode编号到UTF-8编码的相互转换。
Public Declare Function WideCharToMultiByte Lib "kernel32" (ByVal CodePage As Long, _
ByVal dwFlags As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long, _
ByVal lpMultiByteStr As Long, ByVal cchMultiByte As Long, ByVal lpDefaultChar As Long, _
ByVal lpUsedDefaultChar As Long) As Long
Public Declare Function MultiByteToWideChar Lib "kernel32.dll" (ByVal CodePage As Long, _
ByVal dwFlags As Long, ByVal lpMultiByteStr As Long, ByVal cchMultiByte As Long, _
ByVal lpWideCharStr As Long, ByVal cchWideChar As Long) As Long
Public Const CP_UTF8 = 65001
Public Const CP_ACP = 0
Sub QQ1722187970()
'unicode 转 utf-8
'定义要转换的字符串变量
Dim str1 As String
str1 = "我 sadfa\sadf和asdf"
'定义一个变量存储接收实际转换后的字符的字节数
Dim bByte As Long
'先调用WideCharToMultiByte函数获取缓冲区字节数
bByte = WideCharToMultiByte(CP_UTF8, 0, StrPtr(str1), Len(str1), 0, 0, 0, 0)
Debug.Print bByte
'定义一个字节数组变量存储转换后的字符字节
Dim arr() As Byte
ReDim arr(bByte - 1)
'再次调用WideCharToMultiByte函数填充字节到arr数组中
WideCharToMultiByte CP_UTF8, 0, StrPtr(str1), Len(str1), VarPtr(arr(0)), bByte, 0, 0
'遍历字节验证16进制值,可以将字符输入文本文件另存为UTF-8,用二进制查看器打开验证对比
For k = 0 To UBound(arr)
Debug.Print VBA.Hex(arr(k))
Next k
'utf-8 转 unicode
'定义接受转换后的字符串变量
Dim str2 As String
'定义存储实际转换后的字符串字符数的变量
Dim lCount As Long
'先调用MultiByteToWideChar函数获取实际转换后的字符串字符数
lCount = MultiByteToWideChar(CP_UTF8, 0, VarPtr(arr(0)), bByte, StrPtr(str2), 0)
'然后填充缓冲区
str2 = Space(lCount)
'再次调用MultiByteToWideChar函数填充到字符串变量str2中
MultiByteToWideChar CP_UTF8, 0, VarPtr(arr(0)), bByte, StrPtr(str2), lCount
'输出转换后的字符串
Debug.Print str2
End Sub


发表评论