c++ - c++ 中的静态库如何与 name mangle 一起使用?
问题描述
我要求理解,在 c 中没有名称修饰,但 c++ 有。这是如何工作的,例如说我有以下文件
- exlib.hpp 头文件
- exlib.cpp 函数实现文件
- exapp.cpp 主函数使用 exlib
文件 exlib.hpp
#ifndef EXLIB
#define EXLIB
#include <iostream>
int sum(int, int);
int sum(int, int, int);
int sum(int, int, int, int);
#endif
文件 exlib.cpp
#include "exlib.hpp"
int sum(int a, int b)
{
std::cout << "In sum(int, int)" << std::endl;
return a + b;
}
int sum(int a, int b, int c)
{
std::cout << "In sum(int, int, int)" << std::endl;
return a + b + c;
}
int sum(int a, int b, int c, int d)
{
std::cout << "In sum(int, int, int, int)" << std::endl;
return a + b + c + d;
}
文件 exapp.cpp
#include "iostream"
#include "exlib.hpp"
int main()
{
std::cout << "Sum = " << sum(1, 1) << std::endl;
std::cout << "Sum = " << sum(2, 2, 2) << std::endl;
std::cout << "Sum = " << sum(3, 3, 3, 3) << std::endl;
}
编译
$ g++ -c exlib.cpp
$ g++ exapp.cpp exlib.o -o exapp
$ ./exapp
exlib.o 中的总和名称是否错误?
输出:
Sum = In sum(int, int)
2
Sum = In sum(int, int, int)
6
Sum = In sum(int, int, int, int)
12
- 在 main 中的 name mangle 之后如何正确调用 sum ?,对于 name mangling 有任何规则,即在 main 中替换相同的名称或它们如何识别?
- 所有编程语言都以相同的方式命名?
谢谢。
解决方案
虽然 C++ 提供了多态性(即,不同的事物可以在同一范围内通过使用其他特性来区分它们而被命名为相等),但链接器不支持这一点(无论是静态链接还是动态链接)。因此,C++ 编译器使用名称修饰。(其他功能用于装饰原始标识符以产生唯一名称。)
C++ 编译器自己编译每个 C++ 文件(又名翻译单元)。因此,很明显,名称修改必须由该编译器以独特的、可重现的方式完成。即相同的声明必须始终映射到相同的符号。否则,链接器将无法解析(仅)在一个文件中声明并在另一个文件中定义的符号。
但是,没有通用的名称修饰标准(例如,作为 C++ 标准的一部分)。
因此,即使在同一平台上,两个不同编译器生成的二进制代码也可能由于不同的名称修饰(以及其他细节)而不兼容。(对于MS Visual C++,这甚至会导致来自不同版本的二进制文件不兼容。)
为了克服这个问题,存在用于某些平台(例如 Linux)的应用程序二进制接口(ABI)。ABI 的一个细节是标准化的名称修饰。
推荐阅读
- php - 如何将迁移中的更改部署到分解的数据库?
- python-3.x - 无法在 Django 中加载图像
- c# - 团队中具有 MS 身份验证的服务器端 Blazor?
- java - 当忙于旋转的Java线程绑定到物理内核时,是否会因为到达代码中的新分支而发生上下文切换?
- sql - 显示计数最少的数据
- mongodb - 无法在 vs 终端中启动 mongod
- android - 当设备字体大小发生变化时,Android 不会在应用程序中增加文本
- ios - Flutter 上有没有类似 Expo 应用的东西?
- github - github会有多少用户限制搜索?
- google-apps-script - 如何在 Google 表格 onEdit 触发器中获取范围