C++ 的 Name Mangling

1. 什么是Name Mangling

编程语言组织程序,都有一定的可见范围,比如Java的包、C/C++的文件。就像我们平时使用的文件夹一样,有了这些组织机制,变量、函数的命名在一定程度上就可以重复。

但在程序链接时,这些机制多少都要失效一些,就像每个小朋友在家都叫宝宝,到了幼儿园就没办法通过宝宝来区分彼此了。为了解决名字的唯一性,就需要Name Mangling技术。

其实说白了就是对名字进行重新编码的一种规则。比如使用VIM随便打开一个ELF文件,或是链接时,我们有时候可以看到一些类似与下面这样的古怪字符串:

_ZN9NS_QZSOCK10CTcpClient11SendAndRecvEPciRiRjd

这就是经过Name Mangling处理后的符号。

2. GCC中的Name Mangling

C++的复杂度相对于C肯定是复杂很多的,其中表现之一就是C++的名字管理,比如C++支持重载、支持类、命名空间等。不同的函数可以使用相同的函数名、不同的类可以有相同名字的成员变量。这样C++的Name Mangling就会比C复杂很多。

当然,再复杂的,也都不过是各种Tool Chain的一碟小菜。对于C++的Name Mangling规则,C++标准并没有做具体的规定,但各个编译器平台形成了一些事实性的标准,比如GCC的一个简单规则:

A global object with class or namespace qualifiers is coded as
<public name> ::= _Z <qualified name>
where

<qualified name> ::= N[<simple name> ]E

<simple name> ::= <name length> <name>

就是一个类的成员函数可能会被Name Mangling编码为:_Z+N+长度+名字+E

3. GNU Binutils中Name De-Mangling的相关工具

GNU Binutils工具集中提供了Name De-Mangling相关的工具,最典型的c++filt和nm,使用举例如下:

c++filt _ZN9NS_QZSOCK10CTcpClient11SendAndRecvEPciRiRjd
NS_QZSOCK::CTcpClient::SendAndRecv(char*, int, int&, unsigned int&, double)

nm -C bin/play_url.so | grep SendAndRecv
0000000000391090 T NS_QZSOCK::CTcpClient::SendAndRecv(char*, int, int&, unsigned int&, double)
0000000000390a10 T NS_QZSOCK::CUdpClient::SendAndRecv(char*, int, int&, unsigned int&, double)

有了这些工具,再也不怕链接报错和二进制分析时看到的一些奇怪符号了。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏JavaEE

mybatis-plus的使用 ------ 进阶

关于mybatis-plus的简介以及基本使用,我在《mybatis-plus的使用 ------ 入门》一文中已做介绍,此处不再赘述。本文主要对mybatis...

89170
来自专栏Charlie's Road

didReceiveMemoryWarning iOS开发

iPhone下每个app可用的内存是被限制的,如果一个app使用的内存超过20M,则系统会向该app发送Memory Warning消息。收到此消息后,app必...

41830
来自专栏Jimoer

JVM学习记录-类加载器

JVM设计团队把类加载阶段中的“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放到Java虚拟机外面去实现,以便让应用程序自己决定如何去获取所需要的...

8210
来自专栏Java学习网

JSP中session的11个常用方法——收藏备查

session中的属性在当前session中是共享的 session表示一个请求的javax.servlet.http.HttpSession对象。指的是客户端...

25930
来自专栏大内老A

通过自定义ServiceHost实现对WCF的扩展[实例篇]

在《原理篇》中我们谈到了通过自定义ServiceHost对WCF进行扩展的本质,以及在IIS/WAS寄宿情况下ServiceHostFactory的作用。接下来...

29270
来自专栏desperate633

Java并发之“饥饿”和“公平锁”(Starvation and Fairness)java中发生线程饥饿的原因java中实现公平锁公平锁性能考虑

如果一个线程的cpu执行时间都被其他线程抢占了,导致得不到cpu执行,这种情况就叫做“饥饿”,这个线程就会出现饥饿致死的现象,因为永远无法得到cpu的执行。解决...

15610
来自专栏逸鹏说道

C# 温故而知新:Stream篇(四)上

FileStream 目录: 如何去理解FileStream? FileStream的重要性 FileStream常用构造函数(重要) 非托管参数SafeFil...

34050
来自专栏逸鹏说道

C# 温故而知新: 线程篇(四)

线程同步篇 (中):同步工具类的介绍 1 上篇回顾 2 继续介绍基元内核模式中的 monitor类 3 同步句柄:WaitHandle 4 EventW...

32460
来自专栏Java帮帮-微信公众号-技术文章全总结

Java支付宝接口开发【面试+工作】

Java支付宝接口开发【面试+工作】 最近公司在做支付模块,在接入过程中遇到了很多坑,费了不少事,现在分享一下接入方法,也记录一下,以后可能还用的到。用的是支付...

1.3K50
来自专栏运维咖啡吧

Django model update的各种用法介绍

方法一适合更新一批数据,类似于mysql语句update user set username='nick' where id = 1

17820

扫码关注云+社区

领取腾讯云代金券