问题:

原来的2008工程用2010编译后,运行程序出现无法定位程序输入点 *@basic_string@_WU@*和*@basic_string@G@*

解决:

关闭“语言选项”中“将WChar_t视为内置类型”’

转:http://blog.csdn.net/dbzhang800/article/details/6707152

问题

  • MSVC 有一对选项/Zc:wchar_t- 与 /Zc:wchar_t控制wchar_t

  • 于是 wchar_t 可以是 unsigned short 或 __wchar_t(称为原生类型?) 的别名

两个东西混用会怎么样?

首先考虑,会混用么?,是杞人忧天么? 由于 Qt 为 MSVC 提供的二进制包采用的前者/Zc:wchar_t-。考虑:

  • 如果你编译自己的Qt程序时,启用了后者,会怎么样?
  • 如果Qt程序同时使用了其他的C++库,而且这个库编译时采用了后者。会怎么样?

当然

  • 我们可以自己启用 /Zc:wchar_t 来编译Qt解决这样的问题。本文不考虑这个情况。

wchar_t

  • Unicode 4.0标准的5.2节提到:

"The width of wchar_t is compiler-specific and can be as small as 8 bits. Consequently, programs that need to be portable across any C or C++ compilershould not use wchar_t for storing Unicode text. The wchar_t type is intended for storing compiler-defined wide characters, which may be Unicode characters in some compilers."

  • C、C++ 标准对这个 wchar_t 不够明确(以至于C++0x、C1x又引入了char16_t/char32_t)
  • 各编译器实现 wchar_t 时,是通过typedef定义一个别名。在windows下是 16 整数的别名,在linux等平台下,是 32 位整数的别名。

msvc

MSVC,一直以来,wchar_t与其内部两个类型相关

  • unsigned short
  • __wchar_t

wchar_t 可以是二者之一的别名,通过 /Zc:wchar_t- 与 /Zc:wchar_t进行设置

在MSVC2008之前,默认是前者,从MSVC2008开始,默认改为了后者。

例子

直观一点,直接用msvc生成一个动态库,然后看看它导出的符号:

  • 源文件dll.cpp
//dll.cpp
#include <string> __declspec(dllexport) wchar_t * func1()
{
return 0;
} __declspec(dllexport) void func2(wchar_t *)
{
} __declspec(dllexport) std::wstring generateString()
{
return std::wstring();
} __declspec(dllexport) void receiveString(std::wstring str)
{
}
  • 分别用两周wchar_t编译上述文件,分别生成out0.dll 和 out1.dll
cl /EHsc /Zc:wchar_t   /LD dll.cpp  /Feout0.dll
cl /EHsc /Zc:wchar_t- /LD dll.cpp /Feout1.dll
  • 而后,用dumpbin查看导出的符号
dumpbin /EXPORTS out0.dll
dumpbin /EXPORTS out1.dll

导出符号

对于原生类型:注意,其中的 _W 代表 wchar_t 即 __wchar_t的类型

 ?func1@@YAPA_WXZ
?func2@@YAXPA_W@Z
?generateString@@YA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@XZ
?receiveString@@YAXV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@Z

对于unsigned short类型:注意其中的 G 代表wchar_t 即 unsigned short的类型

 ?func1@@YAPAGXZ
?func2@@YAXPAG@Z
?generateString@@YA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@XZ
?receiveString@@YAXV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@@Z

两者改编后的名字不同,如果混用的话:肯定就会因为找不到要找的名字,而出现链接错误了。

对Qt的影响

混用两种 wchar_t 时,

凡是使用 std::wstring 或 wchar_t 的函数都会受影响,比如

QString QString::fromStdWString(const std::wstring & str)
std::wstring QString::toStdWString () const
int QString::toWCharArray(wchar_t * array) const
QString QString::fromWCharArray(const wchar_t * string, int size = -1)

如何解决呢?解决办法就是这种情况下不使用这些函数(似乎很不讲理哈,有些难以接受?)。

不过http://developer.qt.nokia.com上看到有人给出一个方案,恩,尽管还是如我们刚次所说,方法是在msvc下不使用这些函数,只是似乎不是太难接受了。

/*! 自定义的QString到std::wstring转换的封装 */
std::wstring qToStdWString(const QString &str)
{
#ifdef _MSC_VER
return std::wstring((const wchar_t *)str.utf16());
#else
return str.toStdWString();
#endif
} /*! 自定义的 std::wstring 到 QString 转换的封装 */
QString stdWToQString(const std::wstring &str)
{
#ifdef _MSC_VER
return QString::fromUtf16((const ushort *)str.c_str());
#else
return QString::fromStdWString(str);
#endif
}

参考

最新文章

  1. sql 删除表中的重复记录
  2. solr&amp;lucene3.6.0源码解析(三)
  3. Qt5.5.0使用mysql编写小软件源码讲解---顾客信息登记表
  4. Web安全测试之跨站请求伪造(CSRF)篇
  5. ecshop 如果缩略图为空,使用默认图片
  6. 软件工程结对开发——返回一个整数数组中最大子数组的和(JAVA)
  7. Properties读取资源文件的四种方法
  8. VS2010/MFC编程入门之十四(对话框:向导对话框的创建及显示)
  9. 生成bundle和移除bundle
  10. Dialog中显示倒计时,到时自己主动关闭
  11. [DL学习笔记]从人工神经网络到卷积神经网络_3_使用tensorflow搭建CNN来分类not_MNIST数据(有一些问题)
  12. 用R语言 做回归分析
  13. python网络编程之网络主机信息
  14. pytorch学习-AUTOGRAD: AUTOMATIC DIFFERENTIATION自动微分
  15. jq的stop
  16. APP接口调用流程
  17. hdu3966 树链剖分点权模板+线段树区间更新/树状数组区间更新单点查询
  18. react-native-vector-icons 图标库使用
  19. Linux学习(1)- TCP/IP网络协议基础
  20. 【H5】dropload (移动端下拉刷新,上拉加载)

热门文章

  1. HTML5 十大新特性(二)——表单新特性
  2. zookeeper的zoo.cfg的配置
  3. C#日常总结
  4. Python中文乱码
  5. 求子串-KPM模式匹配-NFA/DFA
  6. 说说ASP.NET的表单验证
  7. PHP 常用函数的解释
  8. Thymeleaf3.0内容
  9. 如何在CentOS 7中禁止IPv6
  10. Java集合类学习笔记(List集合)