为什么.o文件中的函数名称与编译后的.cc文件中的函数名称不同?

时间:2013-08-14 22:46:51

标签: linux function compiler-construction makefile g++

我使用以下命令编译了.cc文件,该命令位于Makefile代码中:

bin/bash ../libtool --silent --tag=CXX   --mode=compile g++ -DHAVE_CONFIG_H -I.
-I.. -I../include/ -I..    -g -O2 -MT rtpsession_inet.lo -MD -MP -MF 
.deps/rtpsession_inet.Tpo -c -o rtpsession_inet.lo rtpsession_inet.cc

.cc文件中有一个名为 rtp_session_rtp_recv 的函数。但是,据说当我使用Makefile生成的库时,找不到这个函数的引用。

所以我检查了rtpsession_inet.cc生成的.o文件,发现当函数名改为 _Z20rtp_session_rtp_recvP11_RtpSessionj 时,没有名为 rtp_session_rtp_recv 的函数。

同时,还有其他几个功能改变了他们的名字,例如: rtp_session_rtp_send - >的 _Z20rtp_session_rtp_sendP11_RtpSessionP4msgb

rtp_session_set_remote_addr_full 等功能根本不会改变。

附加字符的含义是什么?我该如何处理这个问题?

我在Linux中编译文件并使用命令

nm rtpsession_inet.o

阅读.o文件。 (包括名称不正确的所有函数都带有T标记,这意味着引用存在)

谢谢!

2 个答案:

答案 0 :(得分:1)

这称为name mangling

这是为了链接器的好处。 C ++编译器能够根据其参数类型解析同名的多个函数。例如,您可能有一个名为print的函数接受int参数,另一个函数接受char*参数。编译器根据您传递给它的参数类型知道哪一个生成调用。

但是,翻译单元之间的调用必须由链接器解决,链接器通常不知道C ++重载规则,并且必须仅根据名称解析调用。因此,C ++编译器使用足够的信息来修饰名称以解决过载问题。

C ++标准没有指定如何完成此操作,但是如果你查看名称,你可以弄清楚如何生成错位名称。

  

我该如何处理这个问题?

编译器和链接器应正确解析调用。你指的是什么问题?

答案 1 :(得分:0)

附加字符是编译器添加的符号“装饰”,用于标识函数/方法签名,即返回类型和参数。它有助于运行时确定在任何给定的调用中调用同名(重载)的许多函数中的哪一个。