正如我在第一部分中提到的,windows APIs 是用TCHARs来定义的,在编译时,它可以根据你是否定义_MBCS或者_UNICODE被编译成MBCS或者Unicode字符。你可以参看第一部分 中对TCHAR的完整描述,这里为了方便,我列出了字符的typedefs
Type |
Meaning |
WCHAR |
Unicode character (wchar_t) |
TCHAR |
MBCS or Unicode character, depending on preprocessor settings |
LPSTR |
string of char (char*) |
LPCSTR |
constant string of char (const char*) |
LPWSTR |
string of WCHAR (WCHAR*) |
LPCWSTR |
constant string of WCHAR (const WCHAR*) |
LPTSTR |
string of TCHAR (TCHAR*) |
LPCTSTR |
constant string of TCHAR (const TCHAR*) |
两个字符串类之间进行转换的常用方式是:先把源字符串转换成一个C语言风格的字符串指针,然后把这个指针传递给目的类型的构造函数。下面这张表显示了怎样把一个字符串转换成一个C语言风格的字符串指针以及哪些类具有接收C语言风格的字符串指针的构造函数。
Class |
string type |
convert to char*? |
convert to const char*? |
convert to wchar_t*? |
convert to const wchar_t*? |
convert to BSTR? |
construct from char*? |
construct from wchar_t*? |
_bstr_t |
BSTR |
yes cast1 |
yes cast |
yes cast1 |
yes cast |
yes2 |
yes |
yes |
_variant_t |
BSTR |
no |
no |
no |
cast to _bstr_t3 |
cast to _bstr_t3 |
yes |
yes |
string |
MBCS |
no |
yes c_str() method |
no |
no |
no |
yes |
no |
wstring |
Unicode |
no |
no |
no |
yes c_str() method |
no |
no |
yes |
CComBSTR |
BSTR |
no |
no |
no |
yes cast to BSTR |
yes cast |
yes |
yes |
CComVariant |
BSTR |
no |
no |
no |
yes4 |
yes4 |
yes |
yes |
CString |
TCHAR |
no6 |
in MBCS builds, cast |
no6 |
in Unicode builds, cast |
no5 |
yes |
yes |
COleVariant |
BSTR |
no |
no |
no |
yes4 |
yes4 |
in MBCS builds |
in Unicode builds |
1、即使 _bstr_t 提供了向非常量指针的转换操作符,修改底层的缓冲区也会已引起GPF如果你溢出了缓冲区或者造成内存泄漏。
2、_bstr_t 在内部用一个 wchar_t* 来保存 BSTR,所以你可以使用 const wchar_t* 来访问BSTR。这是一个实现细节,你可以小心的使用它,将来这个细节也许会改变。
3、如果数据不能转换成BSTR会抛出一个异常。
4、使用 ChangeType(),然后访问 VARIANT 的 bstrVal 成员。在MFC中,如果数据转换不成功将会抛出异常。
5、这里没有转换 BSTR 函数,然而 AllocSysString() 返回一个新的BSTR。
6、使用 GetBuffer() 方法,你可以暂时地得到一个非常量的TCHAR指针。 |
ATL:转换宏是各种字符编码之间进行转换的一种很方便的方式,在函数调用时,它们显得非常有用。ATL转换宏的名称是根据下面的模式来命 名的[源类型]2[新类型]或者[源类型]2C[新类型]。据有第二种形式的名字的宏的转换结果是常量指针(对应名字中的"C")。各种类型的简称如下: A: MBCS string, char* (A for ANSI)
W: Unicode string, wchar_t* (W for wide)
T: TCHAR string, TCHAR*
OLE: OLECHAR string, OLECHAR* (in practice, equivalent to W)
BSTR: BSTR (used as the destination type only)
所以,W2A()宏把一个Unicode字符串转换成一个MBCS字符串。T2CW()宏把一个TCHAR字符串转转成一个Unicode字符串常量。
为了使用这些宏,需要先包含atlconv.h头文件。你甚至可以在非ATL工程中包含这个头文件来使用其中定义的宏,因为这个头文件独立于ATL中 的其他部分,不需要一个_Module全局变量。当你在一个函数中使用转换宏时,需要把USES_CONVERSION宏放在函数的开头。它定义了转换宏 所需的一些局部变量。
当转换的目的类型是除了BSTR以外的其他类型时,被转换的字符串是存在栈中的。所以,如果你想让字符串的生命周期比当前的函数长,你需要把这个字符 串拷贝到其他的字符串类中。当目的类型是BSTR时,内存不会自动被释放,你必须把返回值赋给一个BSTR变量或者一个BSTR封装类以避免内存泄漏。