如何将CComVariant bstr转换为CString 我是一个C++的新手,我已经接管了一个COM项目来修复一些问题。 我正在处理的当前问题是处理UTF8字符串。 我有一段代码: // CString strValue; CStringW strValue; CComVariant* val = &(*result)[i].minValue; switch (val->vt) { case VT_BSTR: //strValue = OLE2CA(val->bstrVal); strValue = OLE2W(val->bstrVal); // Works (*result)[i].name = strValue; // Works (*result)[i].expression = "[" + fieldName + "] = \"" + strValue + "\""; // fails break; case VT_R8: //strValue.Format("%g", val->dblVal); strValue.Format(L"%g", val->dblVal); // Works (*result)[i].name = strValue; // Works (*result)[i].expression = "[" + fieldName + "] = " + strValue; // fails break; case VT_I4: //strValue.Format("%i", val->lVal); strValue.Format(L"%i", val->lVal); // Works (*result)[i].name = strValue; // Works (*result)[i].expression = "[" + fieldName + "] = " + strValue; // fails break; } struct CategoriesData { public: CComVariant minValue; CComVariant maxValue; //CString expression; CStringW expression; //CString name; CStringW name; tkCategoryValue valueType; int classificationField; bool skip; };

如何将CComVariant bstr转换为CString 我是一个C++的新手,我已经接管了一个COM项目来修复一些问题。 我正在处理的当前问题是处理UTF8字符串。 我有一段代码: // CString strValue; CStringW strValue; CComVariant* val = &(*result)[i].minValue; switch (val->vt) { case VT_BSTR: //strValue = OLE2CA(val->bstrVal); strValue = OLE2W(val->bstrVal); // Works (*result)[i].name = strValue; // Works (*result)[i].expression = "[" + fieldName + "] = \"" + strValue + "\""; // fails break; case VT_R8: //strValue.Format("%g", val->dblVal); strValue.Format(L"%g", val->dblVal); // Works (*result)[i].name = strValue; // Works (*result)[i].expression = "[" + fieldName + "] = " + strValue; // fails break; case VT_I4: //strValue.Format("%i", val->lVal); strValue.Format(L"%i", val->lVal); // Works (*result)[i].name = strValue; // Works (*result)[i].expression = "[" + fieldName + "] = " + strValue; // fails break; } struct CategoriesData { public: CComVariant minValue; CComVariant maxValue; //CString expression; CStringW expression; //CString name; CStringW name; tkCategoryValue valueType; int classificationField; bool skip; };,c++,unicode,com,type-conversion,bstr,C++,Unicode,Com,Type Conversion,Bstr,问题在于这一行strValue=OLE2CA(val->bstrVal)当val->bstrVal是类似于此俄文文本的unicode字符串时,将标准值转换为?? 我尝试了几种方法,并在互联网上搜索,但无法将strValue设置为Бзззззз。 CString是否可以包含此类文本,或者是否应更改为其他类型?那是哪一个 最小值可以是VT_BSTR、VT_R8或VT_I4 以下是我迄今为止尝试过的选项: strValue = val->bstrVal; strValue = Utility::

问题在于这一行
strValue=OLE2CA(val->bstrVal)
val->bstrVal
是类似于此俄文文本的unicode字符串时,
将标准值转换为
??

我尝试了几种方法,并在互联网上搜索,但无法将strValue设置为
Бзззззз
CString
是否可以包含此类文本,或者是否应更改为其他类型?那是哪一个

最小值可以是VT_BSTR、VT_R8或VT_I4

以下是我迄今为止尝试过的选项:

strValue = val->bstrVal;
strValue = Utility::ConvertFromUtf8(val->bstrVal);
strValue = Utility::ConvertToUtf8(val->bstrVal);
temp = Utility::ConvertBSTRToLPSTR(val->bstrVal);
strValue = W2BSTR(Utility::ConvertFromUtf8(temp));
strValue = W2BSTR(val->bstrVal);                
strValue = CW2A(val->bstrVal);
strValue = (CString)val->bstrVal;
strValue = Utility::ConvertToUtf8(OLE2W(val->bstrVal));
编辑 助手函数的代码:

CStringA ConvertToUtf8(CStringW unicode) {
    USES_CONVERSION;
    CStringA utf8 = CW2A(unicode, CP_UTF8);
    return utf8;
}

CStringW ConvertFromUtf8(CStringA utf8) {
    USES_CONVERSION;
    CStringW unicode = CA2W(utf8, CP_UTF8);
    return unicode;
}

char* ConvertBSTRToLPSTR (BSTR bstrIn)
{
  LPSTR pszOut = NULL;
  if (bstrIn != NULL)
  {
    int nInputStrLen = SysStringLen (bstrIn);

    // Double NULL Termination
    int nOutputStrLen = WideCharToMultiByte(CP_ACP, 0, bstrIn, nInputStrLen, NULL, 0, 0, 0) + 2; 
    pszOut = new char [nOutputStrLen];

    if (pszOut)
    {
      memset (pszOut, 0x00, sizeof (char)*nOutputStrLen);
      WideCharToMultiByte (CP_ACP, 0, bstrIn, nInputStrLen, pszOut, nOutputStrLen, 0, 0);
    }
  }
  return pszOut;
}
Edit2 我添加了完整的switch语句。 当我将strValue从CString更改为CStringW时,其他情况下会出现错误,如
strValue.Format(“%g”,val->dblVal)
如何解决这个问题

Edit3 我已经修复了一个类似的问题,但它正在转换为
VARIANT
,而不是从:

    val->vt = VT_BSTR;
    const char* v = DBFReadStringAttribute(_dbfHandle, _rows[RowIndex].oldIndex, _fields[i]->oldIndex);
    // Old code, not unicode ready:
    //WCHAR *buffer = Utility::StringToWideChar(v);
    //val->bstrVal = W2BSTR(buffer);
    //delete[] buffer;              
    // New code, unicode friendly:
    val->bstrVal = W2BSTR(Utility::ConvertFromUtf8(v)); 
Edit4 感谢到目前为止所有的帮助,我设法做了一些改变。我在这篇文章中更新了我的初始代码,并添加了该函数的所有代码。我现在只能说这句话:

 (*result)[i].expression = "[" + fieldName + "] = \"" + strValue + "\"";    
我无法连接CStringW值

更多背景信息:该功能是一个开源GIS应用程序的一部分,您可以在其中显示地图(shapefile)。这些地图具有属性数据。此数据以DBase IV格式存储,可以保存unicode/UTF-8文本。我已经做了一个修复(参见Edit3)以在网格视图中正确显示此文本。我现在正在努力的功能是对数据进行分类(分组),例如给相似的值赋予相同的颜色。此类别具有名称和表达式。稍后将解析此表达式以进行实际分组。例如,我有一个州的地图,我想给每个州一个不同的颜色。
如前所述,我是新的C++,我真的在我的舒适区之外。我真的很感激你给我的帮助。我希望你能再次帮助我

如果不将项目转换为支持Unicode的应用程序,您将无法获得一个始终工作的版本

换句话说,要支持BSTR中可能包含的所有字符,您需要一个Unicode CString(CStringW)

您可以继续使用MBCS版本,但在这种情况下,您仍然必须处理Unicode。在这里,使用CStringW可能是一种选择


转换为UTF-8是通过

完成的,如果不将项目转换为支持Unicode的应用程序,您将无法获得始终工作的版本

换句话说,要支持BSTR中可能包含的所有字符,您需要一个Unicode CString(CStringW)

您可以继续使用MBCS版本,但在这种情况下,您仍然必须处理Unicode。在这里,使用CStringW可能是一种选择

转换为UTF-8是通过

BSTR
s“自然”存储UnicodeUTF-16长度前缀字符串来完成的,尽管您可以“拉伸”一个
BSTR
并用它存储一个更通用的长度前缀字节序列(但我不喜欢这种用法)

(有关
BSTR
s的更多详细信息,您将发现非常有趣。)

因此,我正在考虑正常使用的
BSTR
,它存储长度前缀为UTF-16的字符串

如果要将存储在
BSTR
中的UTF-16字符串转换为UTF-8字符串,可以使用带有
CP\u UTF8
标志的
WideCharToMultiByte
Win32 API(如需详细信息,请参阅和)

您可以将目标UTF-8字符串存储在
std::string
类的实例中

p.S.如果您想对UTF-16使用
CStringW
,对UTF-8字符串使用
CStringA
,对UTF-16/8转换使用ATL
CW2A
帮助程序,请注意,您的代码中不需要
USES\u CONVERSION
宏;您可以通过
const&
(const-reference)将输入字符串作为良好的代码卫生:

CStringA Utf8FromUtf16(const CStringW &utf16) {
    CStringA utf8 = CW2A(utf16, CP_UTF8);
    return utf8;
}

重新编辑2

使用
CStringW
尝试使用
strValue.Format(L“%g”,…
L
前缀为
CStringW::Format
生成Unicode UTF-16字符串文字

重新编辑4

我在评论中回答了这个问题,但是为了完整性,用<代码> CSTRIGW< <代码>实例连接字符串文字,考虑用<强> <代码> L来修饰这些文字。

:这定义了一个Unicode UTF-16字符串文字,它基于
wchar\u t
,可以很好地处理
CStringW
对象

(*result)[i].expression = L"[" + fieldName + L"] = \"" + strValue + L"\"";    
BSTR
s“自然”存储UnicodeUTF-16长度前缀字符串,尽管您可以“拉伸”一个
BSTR
并使用它存储一个更通用的长度前缀字节序列(但我不喜欢这种用法)

(有关
BSTR
s的更多详细信息,您将发现非常有趣。)

因此,我正在考虑正常使用的
BSTR
,它存储长度前缀为UTF-16的字符串

如果要将存储在
BSTR
中的UTF-16字符串转换为UTF-8字符串,可以使用带有
CP\u UTF8
标志的
WideCharToMultiByte
Win32 API(如需详细信息,请参阅和)

您可以将目标UTF-8字符串存储在
std::string
类的实例中

p.S.如果您想对UTF-16使用
CStringW
,对UTF-8字符串使用
CStringA
,对UTF-16/8转换使用ATL
CW2A
帮助程序,请注意,您不需要在代码中使用
USES\u CONVERSION
宏;您可以通过
常量和
获取输入字符串(常量参考)良好的卫生规范:

CStringA Utf8FromUtf16(const CStringW &utf16) {
    CStringA utf8 = CW2A(utf16, CP_UTF8);
    return utf8;
}

重新编辑2

尝试使用
strValue.Format(L“%g”…