原文链接:https://zhuanlan.zhihu.com/p/81681440
感谢原作者
杂项
有时候我们使用第三方的库文件,又找不到相应的文档;或者我们查到了函数修饰后的名字,但是太晦涩难懂,怎么翻译成源代码里面的函数声明呢?
- 怎么查看动态库文件里面提供了哪些函数符号?
首先,我们把bar.cpp文件编译成动态库bar.so文件,这个文件提供了函数void bar(int)的实现
要查看bar.so这个库里面提供了哪些函数符号,可以用nm命令
这里我们可以看到,在bar.so文件的代码段(.Text段),有函数_Z3bari的定义。这个_Z3bari就是bar(int)这个函数在名字修饰后在库文件中的名字,链接器就是看这个名字来进行链接活动。nm -C可以查看函数名字修饰之前的名字,大家可以试试看。
- 知道了函数修饰后的名字,怎么推函数声明?
那么,如果我们知道了某个库里面的函数修饰后的名字,有没有什么方法可以反推函数源文件中的声明呢?用c++filt这个命令就可以。还是以上文中_Z3bari为例:
可以看到,_Z3bari这个符号是bar(int)这个函数修饰而成。可能有人会问,为什么不是void bar(int),是不是由于是void型的返回值,所以略去了?这里要注意,函数修饰不会管函数的返回值是什么。函数的返回值不同,而函数名和参数列表一样,经过函数修饰产生的符号是一样的,这也为什么C++规定,函数只有返回值不一样的话,是不能算重载的原因。
- 题外话,有时候我们不愿意让别人看到我们发布的库文件的符号表(泄露内部实现信息),我们也可以将符号信息从库文件中删除(strip命令,还有-fvisibility=hidden)。