在C++中,由于重载等技术的存在,编译器要将函数、结构体、类等等的信息传递给链接器,就不能像C语言那样简单地通过函数名来完成,它需要提供额外的参数信息,而还要和C语言共用链接器,这就需要用到名字改编(name mangling),又叫名字修饰(name decoration)。

名字改编也罢,但由于历史原因,C++没有这方面的标准(C++没有ABI方面的标准,名字改编只是ABI问题的一部分)。于是编译器们各自为政,生成的文件无法通用。

于是:在Windows下,你会发现,同一版本的QtCore4.dll,不同编译器编译出来的无法通用。同一个函数void f(std::wstring s),同一个编译器(MSVC),不同选项(/Zc:wchar_t-/Zc:wchar_t),导出的符号不同。

在Qt中,我们只关注下面两种名字改编:

  • Itanium C++ ABI (GCC3、GCC4,包括MinGW)
  • Microsoft C++ ABI

注:对于Intel编译器,在Windows下和微软ABI一致,在其他平台下和GCC保持一致。

用例子来说话

找个什么例子呢?额... 不妨找个简单的动态库,看看它导出的函数名字吧。Qt的Core和Gui模块都太复杂了,就拿Qt的Test模块来看看吧,QtTest4.dll 或 libQtTest.so.4.8.0

如何看到符号呢?

  • 在windows下,我们可以使用 dumpbin 工具:
dumpbin /EXPORTS qttest4.dll
  • 在linux,我们可以使用 nm 或 readelf 工具:
nm -D libQtTest.so.4.8.0
readelf -Ws libQtTest.so.4.8.0

准备工作完毕,你运行上述命令,即可看到大量的符号出现在屏幕上,我们下面对比Qt Manual给出的函数,看看这些符号(只简单看几个,不然我也看不懂)

放一行太长了,只好这样了,原型/Itanium/Microsoft

1

void QTest::qSleep(int ms)

原型

_ZN5QTest6qSleepEi

Itanium ABI

?qSleep@QTest@@YAXH@Z

Microsoft ABI

2

const char * QTest::currentTestFunction()

 

_ZN5QTest19currentTestFunctionEv

 

?currentTestFunction@QTest@@YAPBDXZ

 

3

int QTest::qExec(QObject *testObject, int argc=0, char **argv=0)

 

_ZN5QTest5qExecEP7QObjectiPPc

 

?qExec@QTest@@YAHPAVQObject@@HPAPAD@Z

 

4

int QTest::qExec(QObject *testObject, const QStringList &arguments)

 

_ZN5QTest5qExecEP7QObjectRK11QStringList

 

?qExec@QTest@@YAHPAVQObject@@ABVQStringList@@@Z

 

5

QTestData & QTest::newRow(const char * dataTag)

 

_ZN5QTest6newRowEPKc

 

?newRow@QTest@@YAAAVQTestData@@PBD@Z

 

6

...

 

...

 

...

 

这堆东西,乱七八糟的,怎么看啊??

试着读读看

void QTest::qSleep(int ms)

原型

_ZN5QTest6qSleepEi

Itanium ABI

?qSleep@QTest@@YAXH@Z

Microsoft ABI

Itanium

_ZN5QTest6qSleepEi

加几个空格

_Z N 5 QTest 6 qSleep E i

_Z

 

C++名字前缀

N...E

复合名字起始字符 QTest::qSleep

 

5 QTest

长度为5的名字QTest

6 qSleep

长度为6的名字qSleep

i

 

参数类型 int

Microsoft

?qSleep@QTest@@YAXH@Z

这个信息有些多,有些乱,比前面的风格差远了。而且很多过时的东西都混在其中。

C++名字前缀

qSleep

最内层的名字

@

名字分隔符

QTest

前一个名字的外层名字

@@

名字结束

Y

函数调用是 near 方式

A

调用惯例__cdecl

X

返回值类型 void

H

参数类型 int

@

参数表结束

Z

表示这是一个函数

关于这些东西的解释,详见calling_conventions

参考

C++ ABI之名字改编(以Qt为例)的更多相关文章

  1. C++ ABI之名字改变,编译器生成符号研究(以Qt为例)

    在C++中,由于重载等技术的存在,编译器要将函数.结构体.类等等的信息传递给链接器,就不能像C语言那样简单地通过函数名来完成,它需要提供额外的参数信息,而还要和C语言共用链接器,这就需要用到名字改编( ...

  2. 以QT为例谈环境搭建

    以QT为例谈环境搭建 作者:哲思 时间:2022.1.5 邮箱:1464445232@qq.com GitHub:zhe-si (哲思) (github.com) 前言 自从实习结束,好久没写博客了. ...

  3. Qt编程之Qt样例表(QSS)

    For a long time, Qt has allowed you to decorate your GUIs with CSS’ish style sheets. Inspired by the ...

  4. C++的二进制兼容问题(以QT为例)

    二进制不兼容带来的问题(需要重新编译库文件,以前编译的失效): http://my.oschina.net/lieefu/blog/505363?fromerr=f5jn7rct 二进制不兼容的原理: ...

  5. qt 单例程序

    1.http://qt.nokia.com的网站把QtSingleApplication 的源代码qtsingleapplication-2.6_1-opensource.zip 下载下来,然后解压缩 ...

  6. 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_ ...

  7. C++中的名字重整技术

    C++ 一直为人诟病之一的原因是他的二进制模块兼容性不好,即ABI(Application Binary Interface)问题.对于同一源代码,不同编译器,甚至同一编译器不同版本都不兼容,其编译出 ...

  8. qt creator源码全方面分析(2-1-1)

    目录 C++的策略/二进制兼容性问题 定义 ABI注意事项 可做与不可做 库程序员的技巧 位标志 使用d指针 故障排除 在没有d指针的情况下将新数据成员添加到类中 添加已重新实现的虚函数 使用新类 向 ...

  9. 自定义的插件如何加载到Qt Designer中(详细)

    要想在Qt Designer中使用自定义控件,必须要使Qt Designer能够知道我们的自定义控件的存在.有两种方法可以把新自定义控件的信息通知给Qt Designer:“升级(promotion) ...

随机推荐

  1. 【一起学源码-微服务】Nexflix Eureka 源码十三:Eureka源码解读完结撒花篇~!

    前言 想说的话 [一起学源码-微服务-Netflix Eureka]专栏到这里就已经全部结束了. 实话实说,从最开始Eureka Server和Eureka Client初始化的流程还是一脸闷逼,到现 ...

  2. acwing 1250. 格子游戏 并查集

    地址 https://www.acwing.com/problem/content/1252/ Alice和Bob玩了一个古老的游戏:首先画一个 n×nn×n 的点阵(下图 n=3n=3 ). 接着, ...

  3. Http请求头安全策略

    今天在网上浪了许久,只是为了找一个很简单的配置,却奈何怎么都找不到. 好不容易找到了,我觉得还是记录下来的好,或许省得许多人像我一样浪费时间. 1.X-Frame-Options 如果网站可以嵌入到I ...

  4. 1065 单身狗 (25分)C语言

    单身狗"是中文对于单身人士的一种爱称.本题请你从上万人的大型派对中找出落单的客人,以便给予特殊关爱. 输入格式: 输入第一行给出一个正整数 N(≤ 50 000),是已知夫妻/伴侣的对数:随 ...

  5. CAP 3.0 版本发布通告

    前言 大家好,我们很高兴宣布 CAP 发布了 3.0 版本正式版. 自从上次 CAP 2.6 版本发布 以来,已经过去了几个月的时间,关注的朋友可能知道,在这几个月的时间里,也发布了几个预览版的 3. ...

  6. 动态规划最短路径LintcodeNO110

    动态规划最短路径LintcodeNO110 简单的dp题,没啥好说的... class Solution { public: /** * @param grid: a list of lists of ...

  7. Java开发中的各种乱码问题

    乱码问题 其实解决乱码问题,就是保证所有的编码格式一致,就不会出现问题. 控制台乱码 修改idea的控制台格式 修改 idea.exe.vmoptions和idea64.exe.vmoptions 在 ...

  8. OpenStack Identity API v3

    Table Of Contents OpenStack Identity API v3 What’s New in Version 3.7 What’s New in Version 3.6 What ...

  9. nor flash之擦除和写入

    最近研究了下nor flash的掉电问题,对nor的掉电有了更多的认识.总结分享如下 擦除从0变1,写入从1变0 nor flash的物理特性是,写入之前需要先进行擦除.擦除后数据为全0xFF,此时写 ...

  10. dp-划分数 (递推)

    问题描述 : 有 n 个无区别的物品 , 将他们分成 不超过 m 堆, 问有多少种分法 ? 例如 : n = 4 , m = 3 , 则总共有的分法是 1 + 2 +1 , 0 + 1 + 3 , 0 ...