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

问题描述 投票:0回答:2

我使用以下命令编译了一个 .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文件,发现没有名为rtp_session_rtp_recv的函数,而函数名称改为_Z20rtp_session_rtp_recvP11_RtpSessionj

同时,还有其他几个函数更改了名称,例如rtp_session_rtp_send -> _Z20rtp_session_rtp_sendP11_RtpSessionP4msgb.

但是rtp_session_set_remote_addr_full等功能根本没有改变。

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

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

nm rtpsession_inet.o

读取.o文件。 (所有函数包括名称不正确的函数都带有T标签,表示引用存在)

谢谢!

linux function makefile g++
2个回答
1
投票

这称为名称修改

这是为了链接器的利益。 C++ 编译器能够根据参数类型解析多个同名函数。例如,您可能有一个名为

print
的函数,它接受
int
参数,另一个函数则接受
char*
参数。编译器根据您传递给它的参数类型知道要生成对哪个调用。

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

C++ 标准没有指定这是如何完成的,但如果您查看名称,您可能可以找出损坏的名称是如何生成的。

我该如何处理这个问题?

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


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.