c++ 中的静态库如何与名称混淆一起使用?
How static library in c++ work with 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 ?,在 main 中替换相同名称或它们如何识别的 name mangling 有任何规则吗?
- 所有的编程语言 mangle 名称都是一样的吗?
谢谢。
而 C++ 提供 Polymorphism (i.e. different things can be named equal in the same scope by using other features for distinguishing them), this is not supported by linkers (neither in statical nor dynamical linking). So, C++ compilers uses name mangling。 (其他特征用于装饰原始标识符以产生唯一名称。)
C++ 编译器自行编译每个 C++ 文件(也称为 translation unit)。因此,很明显,此编译器必须以独特的、可重现的方式进行名称修改。 IE。必须始终将相同的声明映射到相同的符号。
否则,链接器将无法解析(仅)在一个文件中声明并在另一个文件中定义的符号。
但是,没有通用的 name-mangling 标准(例如,作为 C++ 标准的一部分)。
因此,即使在同一平台上,两个不同的编译器生成的二进制代码也可能由于 name-mangling(以及其他细节)不同而不兼容。
(对于 MS Visual C++,这甚至使来自不同版本的二进制文件也不兼容。)
为了克服这个问题,某些平台(例如 Linux)存在 Application Binary Interfaces (ABI)。
ABI 的一个细节是标准化的 name-mangling.
我问这个是为了理解,在 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 ?,在 main 中替换相同名称或它们如何识别的 name mangling 有任何规则吗?
- 所有的编程语言 mangle 名称都是一样的吗?
谢谢。
而 C++ 提供 Polymorphism (i.e. different things can be named equal in the same scope by using other features for distinguishing them), this is not supported by linkers (neither in statical nor dynamical linking). So, C++ compilers uses name mangling。 (其他特征用于装饰原始标识符以产生唯一名称。)
C++ 编译器自行编译每个 C++ 文件(也称为 translation unit)。因此,很明显,此编译器必须以独特的、可重现的方式进行名称修改。 IE。必须始终将相同的声明映射到相同的符号。 否则,链接器将无法解析(仅)在一个文件中声明并在另一个文件中定义的符号。
但是,没有通用的 name-mangling 标准(例如,作为 C++ 标准的一部分)。
因此,即使在同一平台上,两个不同的编译器生成的二进制代码也可能由于 name-mangling(以及其他细节)不同而不兼容。 (对于 MS Visual C++,这甚至使来自不同版本的二进制文件也不兼容。)
为了克服这个问题,某些平台(例如 Linux)存在 Application Binary Interfaces (ABI)。 ABI 的一个细节是标准化的 name-mangling.