nst __wchar_t __pin* pstr = PtrToStringChars(s1);
for ( int i = 0; i < wcslen(pstr); i++ )
(*const_cast<__wchar_t*>(pstr+i))++;
Console::WriteLine ( s1 );
PtrToStringChars()返回一个指向底层字符串的const __wchar_t* ,我们需要固定它,否则垃圾收集器或许会在我们正在管理它的内容的时候移动了它。
在 printf-style 格式函数中使用字符串类
当你在printf()或者类似的函数中使用字符串封装类时你必须十分小心。这些函数包括sprintf()和它的变体,还有TRACE和ATLTRACE宏。因为这些函数没有对添加的参数的类型检查,你必须小心,只能传给它们C语言风格的字符串指针,而不是一个完整的字符串类。
例如,要把一个_bstr_t 字符串传给ATLTRACE(),你必须使用显式转换(LPCSTR) 或者(LPCWSTR):
_bstr_t bs = L"Bob!";
ATLTRACE("The string is: %s in line %d\n", (LPCSTR) bs, nLine);
如果你忘了使用转换符而把整个_bstr_t对象传给了函数,将会显示一些毫无意义的输出,因为_bstr_t保存的内部数据会全部被输出。
所有类的总结
两个字符串类之间进行转换的常用方式是:先把源字符串转换成一个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指针。 |
|