问题:

原来的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
}

参考

wchar_t内置还是别名?小问题一则(升级公司以前代码遇到的问题)的更多相关文章

  1. 微信内置浏览器和小程序的 User Agent 区别及判断方法

    通过UA来判断不同的设备或者浏览器是开发者最常用的方式方法,而对于微信开发和小程序也是同样的一个情况,我们可以通过微信内置浏览器 User Agent 信息来判断其具体类型或者设备. 所以子凡就通过徒 ...

  2. wchar_t是内置还是别名(亲测有效:wchar_t在windows下是16位整数的别名,在linux等平台下是32位整数的别名。MSVC2008开始默认是/Zc:wchar_t)

    接前一篇C++ ABI之名字改编(以Qt为例),继续看看C++名字改编相关的问题. 问题 MSVC 有一对选项/Zc:wchar_t- 与 /Zc:wchar_t控制wchar_t 于是 wchar_ ...

  3. 秒懂ASP.NET中的内置对象

    上篇博客,小编主要简单的介绍了一下ASP.NET中的控件,这篇博客,小编主要简单总结一下ASP.NET中的内置对象,七个内置对象分别是:Request.Response.Application.Coo ...

  4. day5--装饰器函数的信息打印,迭代器,生成器,列表推导式,内置函数

    本文档主要内容: 一 装饰器函数的信息打印 二 迭代器 三 生成器 四 生成器表达式和列表推导式 五 内置函数 一 装饰器函数的信息打印 一个函数一旦被装饰器给装饰后,这个函数的信息使用原来的命令打印 ...

  5. JAVAWEB开发之Session的追踪创建和销毁、JSP具体解释(指令,标签,内置对象,动作即转发和包括)、JavaBean及内省技术以及EL表达式获取内容的使用

    Session的追踪技术 已知Session是利用cookie机制的server端技术.当client第一次訪问资源时 假设调用request.getSession() 就会在server端创建一个由 ...

  6. 从入门到自闭之Python内置函数

    内置函数一 eval:执行字符串类型的代码 exac:执行字符串社类型的代码 eval与exac 禁止使用 hash()作用就是区分可变数据类型与不可变数据类型 # print(hash(" ...

  7. java并发编程(一)可重入内置锁

    每个Java对象都可以用做一个实现同步的锁,这些锁被称为内置锁或监视器锁.线程在进入同步代码块之前会自动获取锁,并且在退出同步代码块时会自动释放锁.获得内置锁的唯一途径就是进入由这个锁保护的同步代码块 ...

  8. 第五天:内置对象(7.Javascript内置对象)

    1)中所术是内置对象,2)中为自定义对象 代码说明如下 2.1.1 定义并创建对象实例方式1,代码如下: <!DOCTYPE html><html lang="en&quo ...

  9. 转:【Java并发编程】之一:可重入内置锁

    每个Java对象都可以用做一个实现同步的锁,这些锁被称为内置锁或监视器锁.线程在进入同步代码块之前会自动获取锁,并且在退出同步代码块时会自动释放锁.获得内置锁的唯一途径就是进入由这个锁保护的同步代码块 ...

随机推荐

  1. activeMQ 安装于使用

    简易教程: http://blog.csdn.net/jiuqiyuliang/article/category/5617711

  2. jq异步上传文件(转载)

    最近在使用ajaxForm,随便把使用方法记下下来,以便以后回顾. 1 ,引入依赖脚本 <script type="text/JavaScript" src="/j ...

  3. Python网络连接

    import appuifw as ui import httplib from os import abort uia=ui.app uin=ui.note uiq=ui.query e32=ui. ...

  4. select两个关联的下拉列表

    今天用到两个关联的select,整理一下代码,仅供参考 如下: <html> <head> <meta charset="UTF-8"> < ...

  5. 支付宝WAP支付接口开发(Node/Coffee语言)

    此博客不更新很久了, 更新的文档在这, 有兴趣到这里围观: http://neutra.github.io/2013/%E6%94%AF%E4%BB%98%E5%AE%9DWAP%E6%94%AF%E ...

  6. Mvc 提交表单的4种方法全程详解

    一,MVC  HtmlHelper方法 Html.BeginForm(actionName,controllerName,method,htmlAttributes){} BeginRouteForm ...

  7. SAP连接电脑串口读数(电子称,磅等数据读取)

    这是几年前做的了,一直都不想分享出来,后来想想为了能够给大家点想法,献出来了... 这是一个电脑读称的方法,一般用COMM口连接的电子设备都可参考. 如果是对串口参数不确定的,可以网上找个串口测试工具 ...

  8. 网页 css 样式 初始化

    body, div, ul, ol, dl, dt, dd, li, dl, h1, h2, h3, h4 {margin:0;padding:0;font-style:normal;font:12p ...

  9. Hammer.js

    一.前言 移动端框架当前还处在初级阶段,但相对于移动端的应用来说已经有很长时间了.虽然暂时还没有PC端开发的需求量大,但移动端的Web必然是一种趋势,在接触移动端脚本的过程中,最开始想到的是juqer ...

  10. oracle date change

    select to_char(sysdate,'yyyy') from dual;-----2016select to_number(to_char(sysdate,'MM'))||'月' from ...