CString( 六 )

对于单个的 BSTR 串来说,这种用法可以工作得很好,这是因为 CString 有一个特殊的构造函式以LPCWSTR(BSTR正是这种类型) 为参数,并将它转化成 ANSI 类型 。专门检查是必须的,因为 BSTR 可能为空值,而 CString 的构造函式对于 NULL 值情况考虑的不是很周到,(感谢 Brian Ross 指出这一点!) 。这种用法也只能处理包含 NUL 终结字元的单字元串;如果要转化含有多个 NULL 字元 串,你得额外做一些工作才行 。在 CString 中内嵌的 NULL 字元通常表现不尽如人意,应该儘量避免 。根据 C/C++ 规则,如果你有一个 LPWSTR,那幺它别无选择,只能和 LPCWSTR 参数匹配 。在 Unicode 模式下,它的构造函式是:CString::CString(LPCTSTR);正如上面所表示的,在 ANSI 模式下,它有一个特殊的构造函式:CString::CString(LPCWSTR);它会调用一个内部的函式将 Unicode 字元串转换成 ANSI 字元串 。(在Unicode模式下,有一个专门的构造函式,该函式有一个参数是LPCSTR类型——一个8位 ANSI 字元串指针,该函式将它加宽为 Unicode 的字元串!)再次强调:一定要检查 BSTR 的值是否为 NULL 。另外还有一个问题,正如上文提到的:BSTRs可以含有多个内嵌的NULL字元,但是 CString 的构造函式只能处理某个串中单个 NULL 字元 。也就是说,如果串中含有嵌入的 NUL位元组,CString 将会计算出错误的串长度 。你必须自己处理它 。如果你看看 strcore.cpp 中的构造函式,你会发现 它们都调用了lstrlen,也就是计算字元串的长度 。注意从 Unicode 到 ANSI 的转换使用带专门参数的 ::WideCharToMultiByte,如果你不想使用这种默认的转换方式,则必须编写自己的转化代码 。如果你在 UNICODE 模式下编译代码,你可以简单地写成:CString convert(BSTR b){if(b == NULL)return CString(_T(""));CString s(b); // in UNICODE modereturn s;}如果是 ANSI 模式,则需要更複杂的过程来转换 。注意这个代码使用与 ::WideCharToMultiByte相同的参数值 。所以你 只能在想要改变这些参数进行转换时使用该技术 。例如,指定不同的默认字元,不同的标誌集等 。CString convert(BSTR b){CString s;if(b == NULL)return s; // empty for NULL BSTR#ifdef UNICODEs = b;#elseLPSTR p = s.GetBuffer(SysStringLen(b) + 1);::WideCharToMultiByte(CP_ACP,// ANSI Code Page0,// no flagsb,// source widechar string-1,// assume NUL-terminatedp,// target bufferSysStringLen(b)+1,// target buffer lengthNULL,// use system default charNULL); // dont care if default useds.ReleaseBuffer();#endifreturn s;} 我并不担心如果 BSTR 包含没有映射到 8 位字元集的 Unicode 字元时会发生什幺,因为我指定了::WideCharToMultiByte的最后两个参数为 NULL 。这就是你可能需要改变的地方 。VARIANT 转换事实上,我从来没有这幺做过,因为我没有用 COM/OLE/ActiveX 编写过程式 。但是我在microsoft.public.vc.mfc 新闻组上看到了 Robert Quirk 的一篇帖子谈到了这种转化,我觉得把他的文章包含在我的文章里是不太好的做法,所以在这里多做一些解释和演示 。如果和他的文章有相孛的地方可能是我的疏忽 。VARIANT 类型经常用来给 COM 对象传递参数,或者接收从 COM 对象返回的值 。你也能自己编写返回 VARIANT 类型的方法,函式返回什幺类型 依赖可能(并且常常)方法的输入参数(比如,在自动化操作中,依赖与你调用哪个方法 。IDispatch::Invoke 可能返回(通过其一个参数)一个 包含有BYTE、WORD、float、double、date、BSTR 鹊?VARIANT 类型的结果,(详见 MSDN 上的 VARIANT 结构的定义) 。在下面的例子中,假设 类型是一个BSTR的变体,也就是说在串中的值是通过 bsrtVal 来引用,其优点是在 ANSI 套用中,有一个构造函式会把 LPCWCHAR 引用的值转换为一个 CString(见 BSTR-to-CString 部分) 。在 Unicode 模式中,将成为标準的 CString构造函式,参见对预设::WideCharToMultiByte转换的告诫,以及你觉得是否可以接受(大多数情况下,你会满意的) 。VARIANT vaData;vaData = m_com.YourMethodHere();ASSERT(vaData.vt == VT_BSTR);CString strData(vaData.bstrVal);