PB PB中字符编码转换[ansi, UTF8, Unicode]
利用windows系统自带的API函数进行转换,附带函数参数说明,如果还需要更详细的资料可以网上搜索:
int MultiByteToWideChar( UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr,int cchMultiByte, LPWSTR lpWideCharStr,int cchWideChar );
CodePage:指定执行转换的代码页,这个参数可以为系统已安装或有效的任何代码页所给定的值。
dwFlags: 指定是否转换成预制字符或合成的宽字符,对控制字符是否使用像形文字,以及怎样处理无效字符。
lpMultiByteStr:指向将被转换字符串的字符。
cchMultiByte:指定由参数lpMultiByteStr指向的字符串中字节的个数。如果lpMultiByteStr指定的字符串以空字符终止,可以设置为-1(如果字符串不是以空字符中止,设置为-1可能失败,可能成功),此参数设置为0函数将失败。
lpWideCharStr:指向接收被转换字符串的缓冲区。
cchWideChar:指定由参数lpWideCharStr指向的缓冲区的字符个数。若此值为零,函数返回缓冲区所必需的宽字符数,在这种情况下,lpWideCharStr中的缓冲区不被使用。
返回值:
如果函数运行成功,并且cchWideChar不为零,返回值是由lpWideCharStr指向的缓冲区中写入的宽字符数;
如果函数运行成功,并且cchMultiByte为零,返回值是接收到待转换字符串的缓冲区所需求的宽字符数大小。
如果函数运行失败,返回值为零。
int WideCharToMultiByte(UINT CodePage,DWORD dwFlags,LPWSTR lpWideCharStr,int cchWideChar,LPCSTR lpMultiByteStr,int cchMultiByte,LPCSTR lpDefaultChar,PBOOL pfUsedDefaultChar);
CodePage:指定执行转换的代码页,这个参数可以为系统已安装或有效的任何代码页所给定的值[说白了就是什么字符编码转换成unicode编码。常用CP_ACP(0)和CP_UTF8(65001)
dwFlags: 指定如何处理没有转换的字符,但不设此参数函数会运行的更快一些,我都是把它设为0。
lpWideCharStr: 待转换的宽字符串。
cchWideChar: 待转换宽字符串的长度,-1表示转换到字符串结尾。
lpMultiByteStr: 接收转换后输出新串的缓冲区。
cbMultiByte: 输出缓冲区大小,如果为0,lpMultiByteStr将被忽略,函数将返回所需缓冲区大小而不使用lpMultiByteStr。
lpDefaultChar: 指向字符的指针, 在指定编码里找不到相应字符时使用此字符作为默认字符代替。如果为NULL则使用系统默认字符。
对于要求此参数为NULL的dwFlags而使用此参数,函数将失败返回并设置错误码ERROR_INVALID_PARAMETER。
lpUsedDefaultChar:开关变量的指针,用以表明是否使用过默认字符。对于要求此参数为NULL的dwFlags而使用此参数,函数将失败返回并设置错误码ERROR_INVALID_PARAMETER。
lpDefaultChar和lpUsedDefaultChar都设为NULL,函数会更快一些。
返回值:
如果函数成功,且cbMultiByte非0,返回写入lpMultiByteStr的字节数(包括字符串结尾的null);cbMultiByte为0,则返回转换所需 字节数。函数失败,返回0。
注意:指针lpMultiByteStr和lpWideCharStr必须不一样。如果一样,函数将失败,GetLastError将返回ERROR_INVALID_PARAMETER的值。
PB中的函数声明:
FUNCTION long WideCharToMultiByte(uint CodePage, ulong dwFlags, ref blob lpWideCharStr, long cchWideChar, ref blob lpMultiByteStr, long cbMultiByte, long lpDefaultChar,long lpUsedDefaultChar) Library "kernel32.dll" FUNCTION long MultiByteToWideChar(uint CodePage, ulong dwFlags, ref blob lpMultiByteStr,long cchMultiByte,ref blob lpWideCharStr, long cchWideChar) LIBRARY "kernel32.dll"
注意:
在WideCharToMultiByte 函数中cchWideChar这个参数表示多少个unicode字符需要转换,其它语言我不知道在PB中统计出来需要转换的大写是字节数,因为unicode是2个自己的,所以需要除以2得出unicode字符数,同样的道理 MultiByteToWideChar 函数中cchMultiByte 是要乘以2的字节控件才能容纳转换后unicode。
刚开始不明白一直转换出来是乱码,原因就在这里,真是坑爹的参数。可能是PB没有宽字符的概念吧,统一都用字节做单位。
MultiByteToWideChar 中 lpWideCharStr, cchWideChar 两个参数,看参考文档是要设置为NULL值,但是在PB里面调用的话一定要变成0,要是也是null执行,函数就返回0,报参数错误。。。原因未知。。
还有就是常识: PB long型才是对应系统API的integer整型,所以声明的时候要注意了。
//---------------------of_unicode_utf8-----------------------------
// 函数: of_unicode_utf8()
//--------------------------------------------------------------------
// 描述: Unicode编码转换为UTF8编码
//--------------------------------------------------------------------
// 参数:
// reference blob ablb_unicode
// reference blob ablb_UTF8
//--------------------------------------------------------------------
// 返回值: long 转换后的字节数
//========================================
long ll_Unicode_Size, ll_UTF8_Size ll_Unicode_Size = len(ablb_unicode) if ll_Unicode_Size < 1 then return 0 end if ll_Unicode_Size = ll_Unicode_Size/2 //获取转换需要的字节数 ll_UTF8_Size = WideCharToMultiByte(CP_UTF8, 0, ablb_unicode, ll_Unicode_Size, ablb_utf8, 0, 0, 0) if ll_UTF8_Size < 1 then return 0 end if ablb_utf8 = Blob(space(ll_UTF8_Size)) ll_UTF8_Size = WideCharToMultiByte(CP_UTF8, 0, ablb_unicode, ll_Unicode_Size, ablb_utf8, ll_UTF8_Size, 0, 0) if ll_UTF8_Size < 1 then return 0 end if return ll_UTF8_Size
//------------------of_utf8_unicode---------------------------------
// 函数: of_utf8_unicode()
//--------------------------------------------------------------------
// 描述: UTF-8 编码转换为 Unicode 编码格式
//--------------------------------------------------------------------
// 参数:
// reference blob ablb_UTF8
// reference blob ablb_Unicode
//--------------------------------------------------------------------
// 返回值: integer 多少字节被转换
//========================================
long ll_UTF8_Size long ll_Unicode_Byte_Size, ll_Unicode_WChar_Size blob lblb_null setnull(lblb_null) ll_UTF8_Size = len(ablb_UTF8) //获取转换后需要的内存空间 ll_Unicode_WChar_Size = MultiByteToWideChar(CP_UTF8, 0, ablb_UTF8, ll_UTF8_Size, lblb_null, 0) if ll_Unicode_WChar_Size < 1 then return 0 end if ll_Unicode_Byte_Size = ll_Unicode_WChar_Size * 2 ablb_Unicode = blob(space(ll_Unicode_Byte_Size)) //开始转换 ll_Unicode_WChar_Size = MultiByteToWideChar(CP_UTF8, 0, ablb_UTF8, ll_UTF8_Size, ablb_Unicode, ll_Unicode_Byte_Size) if ll_Unicode_WChar_Size < 1 then return 0 end if return ll_Unicode_Byte_Size
//-----------------------------------------------of_ANSI_Unicode---
// 函数: of_ANSI_Unicode()
//--------------------------------------------------------------------
// 描述: ANSI 编码转换为 Unicode 编码格式
//--------------------------------------------------------------------
// 参数:
// value string as_ANSI
// reference blob rblb_Unicode
//--------------------------------------------------------------------
// 返回值: long 多少字节被转换
//========================================
long ll_ANSI_Size long ll_Unicode_Byte_Size, ll_Unicode_WChar_Size blob lblb_ANSI blob lblb_null setnull(lblb_null) lblb_ANSI = BLOB(as_ansi) ll_ANSI_Size = len(lblb_ANSI) //获取转换后需要的内存空间 ll_Unicode_WChar_Size = MultiByteToWideChar(CP_ACP, 0, lblb_ANSI, ll_ANSI_Size, lblb_null, 0) if ll_Unicode_WChar_Size < 1 then return 0 end if ll_Unicode_Byte_Size = ll_Unicode_WChar_Size * 2 rblb_unicode = blob(space(ll_Unicode_Byte_Size)) //开始转换 ll_Unicode_WChar_Size = MultiByteToWideChar(CP_ACP, 0, lblb_ANSI, ll_ANSI_Size, rblb_unicode, ll_Unicode_Byte_Size) if ll_Unicode_WChar_Size < 1 then return 0 end if return ll_Unicode_Byte_Size
//---------------------of_ANSI_UTF8--------------------------------
// 函数: of_ANSI_UTF8()
//--------------------------------------------------------------------
// 描述: ANSI 编码 转换为 UTF8 编码
//--------------------------------------------------------------------
// 参数:
// reference string as_ANSI
// reference blob ablb_UTF8
//--------------------------------------------------------------------
// 返回值: long 转换后的字节数
//========================================
blob lblb_Unicode long ll_Unicode_Size, ll_UTF8_Size if isnull(as_ansi) or len(as_ansi) = 0 then return 0 end if lblb_Unicode = ToUnicode(as_ansi) ll_Unicode_Size = len(lblb_Unicode) of_ANSI_Unicode(as_ansi, lblb_Unicode) ll_Unicode_Size = len(lblb_Unicode) if ll_Unicode_Size < 1 then return 0 end if ll_UTF8_Size = of_unicode_utf8( lblb_Unicode, ablb_utf8) return ll_UTF8_Size
//--------------------of_UTF8_ANSI--------------------------------
// 函数: n_cst_utilities::of_UTF8_ANSI()
//--------------------------------------------------------------------
// 参数:
// reference blob ablb_UTF8
// reference string as_ANSI
//--------------------------------------------------------------------
// 返回值: integer
//========================================
blob lblb_Unicode, lblb_ANSI long ll_Unicode_Size, ll_UTF8_Size ll_Unicode_Size = of_UTF8_Unicode(ablb_utf8, lblb_Unicode) if ll_Unicode_Size < 1 then return 0 end if as_ansi = FromUnicode(lblb_Unicode) return len(as_ansi)