先看几个全局函数的定义:
一、 U8toW()函数
这个全局函数有两个定义,都声明在tapi32u8.h中,声明如下:
//tapi32u8.h/line29
int U8toW(const char *src, WCHAR *dst, int bufsize, int max_len=-1);
WCHAR *U8toW(const char *src, BOOL noStatic=FALSE);
先看返回值为int的那一个,定义如下:
//tapi32u8.cpp/line419
int U8toW(const char *src, WCHAR *dst, int bufsize, int max_len)
{
int len = ::MultiByteToWideChar(CP_UTF8, 0, src, max_len, dst, bufsize);
if (len == 0 && dst && bufsize > 0)
{
if ((len = (int)wcsnlen(dst, bufsize)) == bufsize)
{
dst[--len] = 0;
}
}
return len;
}
函数释义:
(1)首先调用MultiByteToWideChar()函数。如果函数运行成功,并且bufsize不为零的话,返回值len是由des指向的缓冲区中写入的宽字符的个数;如果函数运行成功,并且bufsize为零,返回值len是接收到待转换字符串src的缓冲区所需求的宽字符数的大小;如果函数运行失败,返回值len为0;maxlen设置为-1表示指定src字符串以空字符终止。
(2)CP_UTF8:使用UTF-8转化
(3)如果len为0,且des不为空,且bufsize也大于0,也就是说定义好了接收缓冲区,但是函数运行失败了,就进行如下操作,否则直接返回len的值。如果函数运行失败,调用wcsnlen函数。如果des字符串的长度大于bufsize的大小的话,就将字串的第bufsize-1位置设为null。否则返回len.
(4)size_t wcsnlen(const wchar_t *str, size_t numberOfElements);
str是以NULL结尾的字符串。numberOfElements表示字符串缓冲区的大小。函数将返回字符串中的字符数,不包括以NULL结尾的字符。str的长度严格小于numberOfElements;如果字符串的第一个numberOfElements字节中不包含null,那么就返回numberOfElements来指示错误条件。
然后看返回值为WCHAR *的实现类型:
WCHAR *U8toW(const char *src, BOOL noStatic)
{
static WCHAR *_wbuf = NULL;
WCHAR *wtmp = NULL;
WCHAR *&wbuf = noStatic ? wtmp : _wbuf;
if (wbuf)
{
delete [] wbuf;
wbuf = NULL;
}
int len;
if ((len = U8toW(src, NULL, 0)) > 0) {
wbuf = new WCHAR [len + 1];
U8toW(src, wbuf, len);
}
return wbuf;
}
函数释义:
wbuf是一个WCHAR*的引用变量,根据noStatic的值,来确定是引用一个静态宽字符指针还是普通的宽字符指针。静态变量在函数结束后不销毁但是只在该函数内有效。
我的理解:如果定义一个指针是静态的,那么这个指针定义的那个内存单元或者内存空间的内容是可以改变的。这里的返回值就是指针,所以普通的指针就可以了。
接下来如果wbuf引用的这个指针不为空的话,将其置空。
定义len,并赋值它为src转换为宽字符的数量,这里不包含最后一位NULL。然后初始化宽字符数组并用wbuf引用的指针指向它。
再次调用U8ToW()函数,将src转换成宽字符写入wbuf中。
返回wbuf.
二、AtoW()函数。
AtoW()函数同样有两个实现:
先看声明:
//tapi32u8.h/line41
int AtoW(const char *src, WCHAR *dst, int bufsize, int max_len=-1);
WCHAR *AtoW(const char *src, BOOL noStatic=FALSE);
首先看返回值为int类型的AtoW的定义:
//tapi32u8.cpp
int AtoW(const char *src, WCHAR *dst, int bufsize, int max_len)
{
int len = ::MultiByteToWideChar(CP_ACP, 0, src, max_len, dst, bufsize);
if (len == 0 && dst && bufsize > 0)
{
if ((len = (int)wcsnlen(dst, bufsize)) == bufsize)
{
dst[--len] = 0;
}
}
return len;
}
函数释义:
使用CP_ACP即ANSI字符集合转换。其余同U8toW()函数。
接着看返回值为WCHAR*类型的AtoW()的定义:
//tmisc.cpp/line822
WCHAR *AtoW(const char *src, BOOL noStatic)
{
static WCHAR *_wbuf = NULL;
WCHAR *wtmp = NULL;
WCHAR *&wbuf = noStatic ? wtmp : _wbuf;
if (wbuf)
{
delete [] wbuf;
wbuf = NULL;
}
int len;
if ((len = AtoW(src, NULL, 0)) > 0)
{
wbuf = new WCHAR [len + 1];
AtoW(src, wbuf, len);
}
return wbuf;
}
函数释义:
类似U8ToW()函数。转换后返回的为src指向的字符串的ANSI版本。
三、 Wstr类
Wstr类的声明如下:
//tapi32u8.h/line69
class Wstr
{
WCHAR *s;
public:
Wstr(const char *_s, StrMode mode=BY_UTF8)
{
s = _s ? mode == BY_UTF8 ? U8toW(_s, TRUE) : AtoW(_s, TRUE) : NULL;
}
Wstr(int len) { if (len) { s = new WCHAR [len]; *s = 0; } else { s = NULL; } }
~Wstr() { delete [] s; }
operator const WCHAR *() { return s; }
operator const void *() { return s; } // for V()
WCHAR *Buf() { return s; }
};
(1)成员变量
WHCAR类型的指针s;
(2)构造函数
Wstr(const char *_s, StrMode mode=BY_UTF8)
{
s = _s ? mode == BY_UTF8 ? U8toW(_s, TRUE) : AtoW(_s, TRUE) : NULL;
}
可接受一个或者两个参数的构造函数,接受一个参数的构造函数的时候,参数mode指定为BY_UTF8,构造函数将传进来的参数按照mode的值进行宽窄字符转换。如果mode是BY_UTF8的话,调用U8toW()函数,赋值给s。如果mode不是BY_UTF8的话,调用AtoW函数。将转换后的_s赋值给s;
(3)构造函数
Wstr(int len)
{
if (len)
{
s = new WCHAR [len]; *s = 0;
}
else
{
s = NULL;
}
}
若len为0,初始化s空。如果len大于0,初始化一个len长度的宽字符数组,并置第一位为0;
(4)析构函数
~Wstr()
{
delete [] s;
}
销毁s指向的那个构造时候申请的内存区。
(5)返回s的函数
operator const WCHAR *() { return s; }
operator const void *() { return s; } // for V()
WCHAR *Buf() { return s; }
调用运算符()重载。当遇到强制转换为WCHAR*,void*,或者调用Buf()函数的时候,就返回成员变量s;
四、枚举类型StrMode.
声明如下:
//tlib.h/line251
enum StrMode { BY_UTF8, BY_MBCS };
此枚举类型仅只包含两个值,意义在于选择宽窄字符集。UNICODE和MBCS的区别,看另外一篇博客。