将 std::wstring 从 Visual Studio 移植到 mingw gcc

Posted

技术标签:

【中文标题】将 std::wstring 从 Visual Studio 移植到 mingw gcc【英文标题】:porting std::wstring from visual studio to mingw gcc 【发布时间】:2015-02-20 22:10:50 【问题描述】:

我正在将一些代码从 Visual Studio 移植到 mingw gcc。 我遇到了这个说法

if ( mnode.GetTag() == _T( "val" ) )    
        return  true;

这是GetTag()方法的定义

const std::wstring &GetTag() const;

我收到了错误

error: no matching function for call to 'std::basic_string<wchar_t>::basic_string(const char [6])'|

现在在阅读this 之后,我仍然不确定如何解决这个问题。 关于为什么显示此错误的任何建议?是因为 wstring 吗?

【问题讨论】:

使用 MinGW 构建时定义的 _T() 宏是什么? 听起来你没有定义_UNICODE。见:msdn.microsoft.com/en-us/library/dybsewaf.aspx @JamesFranco,T 变体根据定义的预处理器值使用窄字符串或宽字符串。它们已经过时了。明确使用窄字符串或宽字符串。与 Windows API 交互时,更喜欢使用宽版本。 @JamesFranco __T() 只是另一个宏,如果你一直追踪它,你会看到它扩展到 L 或者什么都没有,这取决于 UNICODE (或者可能是 @987654330 @) 预处理器符号是否定义。听起来您没有定义它,在这种情况下,看起来您复制粘贴了错误的错误语句。与您显示的代码行对应的应该是 const char[4] 而不是 const char[6] 加重不适。实际上有 两组 组宏和限定符。 UNICODE_UNICODE,以及 TEXT()_T()。一组通过(并用于)Windows API 提供,另一组通过 MSVC 运行时提供。是啊,真有趣。 【参考方案1】:

您的问题似乎是未定义 _UNICODE 预处理器宏。 MSDN explains 这如何影响 _T() 宏中包含的字符串文字。

 pWnd->SetWindowText( _T("Hello") );

定义_UNICODE 后,_T 将文字字符串转换为以L 为前缀的形式;否则,_T 会翻译不带 L 前缀的字符串。

L 前缀添加到字符串文字表明它是wide string literal,并且std::wstring(或std::basic_string&lt;wchar_t&gt;)定义了一个operator== 重载,它采用wchar_t const * 参数,从而允许您的代码编译。

请注意,如果您要在 Windows API 中调用函数,还有一个相关的 UNICODE 宏。 Raymond Chen 在this post 中很好地解释了这种疯狂。

因此,解决问题的一种方法是将 _UNICODEUNICODE 预处理器符号添加到 gcc 命令行。

但不要这样做!这是我对此事的看法——而不是依赖于晦涩的宏,只需手动在字符串文字前加上 L。尤其是在这种情况下,既然你说GetTag() 总是返回一个wstring const&amp;,我会说对那个字符串文字使用_T() 宏是一个错误。

即便如此,在调用 Windows API 函数时,只需显式调用宽字符版本即可。例如,将对GetWindowText 的调用替换为GetWindowTextW

【讨论】:

以上是关于将 std::wstring 从 Visual Studio 移植到 mingw gcc的主要内容,如果未能解决你的问题,请参考以下文章

从 std::string 和 std::wstring 获取 char 整数值

将 std::wstring 的内容从 C++ 返回到 C#

将 std::wstring 移植到 gcc cygwin

如何使用 PInvoke 将 std::wstring 从 C++ 返回到 C# 而无需编写字符串缓冲区转换 [重复]

string和wstring相互转换

从 DLL 返回 std::wstring 是不是安全?