标签:
接前一篇C++ ABI之名字改编(以Qt为例),继续看看C++名字改编相关的问题。
MSVC 有一对选项/Zc:wchar_t- 与 /Zc:wchar_t控制wchar_t
于是 wchar_t 可以是 unsigned short 或 __wchar_t(称为原生类型?) 的别名
两个东西混用会怎么样?
首先考虑,会混用么?,是杞人忧天么? 由于 Qt 为 MSVC 提供的二进制包采用的前者/Zc:wchar_t-。考虑:
当然
我们可以自己启用 /Zc:wchar_t 来编译Qt解决这样的问题。本文不考虑这个情况。
"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."
MSVC,一直以来,wchar_t与其内部两个类型相关
__wchar_t
wchar_t 可以是二者之一的别名,通过 /Zc:wchar_t- 与 /Zc:wchar_t进行设置
在MSVC2008之前,默认是前者,从MSVC2008开始,默认改为了后者。
直观一点,直接用msvc生成一个动态库,然后看看它导出的符号:
//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)
{
}
cl /EHsc /Zc:wchar_t /LD dll.cpp /Feout0.dll
cl /EHsc /Zc:wchar_t- /LD dll.cpp /Feout1.dll
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
两者改编后的名字不同,如果混用的话:肯定就会因为找不到要找的名字,而出现链接错误了。
当混用两种 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
}
http://stackoverflow.com/questions/4667266/c-name-mangling-by-hand
http://labs.qt.nokia.com/2009/08/12/some-thoughts-on-binary-compatibility/
http://developer.qt.nokia.com/wiki/toStdWStringAndBuiltInWchar_SimplifiedChinese
http://blog.csdn.net/dbzhang800/article/details/6707152
wchar_t内置还是别名(wchar_t在windows下是16整数的别名,在linux等平台下是32位整数的别名。MSVC2008开始默认是/Zc:wchar_t)
标签:
原文地址:http://www.cnblogs.com/findumars/p/5104245.html