GNU C++ 编译器的换名规则 #
全局变量 #
不做任何修改
全局函数 #
以_Z
开头,然后是函数名字符的个数,接着是函数名,最后是函数参数的别名。
类或命名空间中的变量或函数 #
以_ZN
开头,然后是变量或函数所在名字空间或类名字的字符长度,然后接着的是真正的名字空间或类名,然后是变量或函数名的长度和变量或函数名,后面紧跟字母E
,最后如果是函数的话则跟参数别名,如果是变量则什么都不用加。
构造函数和析构函数 #
以_ZN
开头,然后是构造函数所在名字空间和类名字的字符长度,然后接着的是真正的名字空间或类名,然后构造函数接C1
或者C2
,析构函数接D1
或者D2
,然后加上字母E
,最后接函数参数别名结束。
函数的参数 #
是基本类型时 #
参数类型 | 参数别名 |
---|---|
void | v |
wchar_t | w |
bool | b |
char | c |
signed char | a |
unsigned char | h |
short | s |
unsigned short | t |
int | i |
unsigned int | j |
long | l |
unsigned long | m |
long long或__int64 | x |
unsigned long long或unsigned __int64 | y |
__int128 | n |
unsigned __int128 | o |
float | f |
double | d |
long double或__float80 | e |
__float128 | g |
是类或结构体时 #
在类或者结构体名字前加上类或结构体名的字符长度
例如,全局函数int structure_func(int i, struct test s, double d)
,其经过符号改编后,函数名变成了_Z14structure_funci4testd
。
是指针(*)时 #
含有指针时,该参数的别名是P
(大写)加上该指针指向的参数类型的别名。当参数为指针的指针时,该参数的别名是PP
加上所指向的参数类型的别名,以此类推。
是一维数组时 #
和参数是指针的处理方式一样,也是P
加上作为参数的数组其元素类型的别名。
是多维数组时 #
第一维可以看做是指针,其它维则看做是数组。
当函数参数中含有多维数组时,以P
(代表数组的第一维)开始,后面接A
加上各维数组的长度,以_
间隔,最后以下划线加数组元素类型的别名结束。
例如,全局函数void multi_array_func(int a[10][10][20][30])
,其经过符号改编后,函数名变成了_Z16multi_array_funcPA10_A20_A30_i
。
含有const修饰符时 #
以K
(大写)开始,后面接修饰参数类型的别名
是引用(&)时 #
以R
(大写)开始,后面加上该引用所引用的变量类型的别名。
例如,全局函数void ref_const_func(const int &i)
,其经过符号改编后,函数名变成了_Z14ref_const_funcRKi
。
是别的命名空间中的类或结构体 #
该参数的别名是N
(大写),加上空间名的长度,再加上空间名,接着是类或结构名的长度和类或结构的名字,最后以E
(大写)结束。
总结 #
- 除了全局变量不用做改编之外,其它所需要改编符号的时候,都是以
_Z
开始;- 若想表示某个符号是在命名空间或类中的,要以
N
开始,以E
结束;
- 若想表示某个符号是在命名空间或类中的,要以
- 所有的名字空间名、类名、函数名或变量名,改编的时候都是名字所包含的字符数加上真正的名字;
- 所有的名字按照从外层到里层的顺序进行改编;
- 如果是函数的话,所有的参数按照前后出现的顺序进行改编。