C++ 符号修饰

什么是符号修饰?

在 C++ 中,符号修饰是指编译器对函数和变量名进行的一种变换或修饰。这种修饰是为了解决 C++ 的函数重载、命名空间和类等特性引入的命名冲突问题。通过符号修饰,编译器可以在目标文件中唯一标识不同的实体,确保在链接阶段能够正确地找到并匹配相应的函数或变量。

符号修饰的原理

C++ 编译器通过一种名为“名字翻译”(Name Mangling)的技术来实现符号修饰。名字翻译将源代码中的函数和变量名转换成目标文件中的唯一标识符。这种转换过程包括以下几个方面:

1. 函数重载

C++ 允许函数重载,即在同一作用域内定义多个同名函数,但它们的参数类型或个数不同。为了在目标文件中区分这些重载函数,编译器会根据函数的参数类型和个数生成不同的符号。

2. 命名空间

命名空间是 C++ 中组织代码的一种方式,但它可能导致相同名字的函数或变量在目标文件中发生冲突。符号修饰通过在符号前添加命名空间信息,解决了这一问题。

3. 类成员函数

类的成员函数通常需要包含类的信息,以便正确访问对象的成员。符号修饰通过在符号中嵌入类的信息,确保了正确的成员函数匹配。

示例:符号修饰的实际应用

考虑以下 C++ 代码片段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>

namespace Math {
class Calculator {
public:
int add(int a, int b);
};
}

int Math::Calculator::add(int a, int b) {
return a + b;
}

int main() {
Math::Calculator calc;
std::cout << calc.add(3, 4) << std::endl;
return 0;
}

通过编译并查看符号表,我们可以看到 Math::Calculator::add 函数的符号修饰:

1
2
$ nm a.out | grep add
000000000040157e T _ZN4Math9Calculator3addEii

在这个例子中,符号 _ZN4Math9Calculator3addEii 就是经过修饰的 Math::Calculator::add 函数名。

如何处理符号修饰

在正常情况下,大多数 C++ 程序员在日常编程中不需要过多关注符号修饰。编译器会自动处理符号修饰,而开发者通常只需使用函数和变量的原始名称即可。只有在涉及到库的开发、跨语言交互或者遇到符号冲突的特殊情况下,才需要更深入地了解符号修饰。

字符串三剑客: sed

sed 小技巧:

  1. 替换字符串:

    1
    sed 's/old_string/new_string/g' filename

    这将在文件中将所有的 old_string 替换为 new_string

  2. 删除行:

    1
    sed '/pattern/d' filename

    这将删除包含指定模式的行。

字符串三剑客: grep

grep 命令小技巧

  1. 简单搜索:

    1
    grep "pattern" filename

    这将在文件中搜索匹配指定模式的行。

  2. 忽略大小写:

    1
    grep -i "pattern" filename

    -i 选项将忽略大小写。

搭建 sftp server

有些时候我们开发需要接触涉及到一些sftp接口,比如 sftp 上传文件, sftp下载文件,这时候可以用 docker 快速的搭建一个sftp server 用于测试开发。

拉镜像

1
docker pull atmoz/sftp

启动 sftp 服务

1
docker run -d -v /path/to/shared/folder:/home/username/upload -p 2222:22 -e SFTP_USERS=username:password:::upload atmoz/sftp
  • /path/to/shared/folder 是想要共享的文件夹的本地路径。
  • username 是要创建的用户名。
  • password 是用户的密码。
  • -p 2222:22 将容器的 22 端口映射到主机的 2222 端口,这是 SFTP 默认的端口。

测试

1
sftp -P 2222 username@localhost:/upload/xxx xxx
  • 要用 sftp 而不是 scp
  • 下载路径是 /upload/, 而不是 /home/username/upload

怎样编写 OpenAPI

OpenAPI

OpenAPI 是一种与语言无关的文档,用来描述 web 服务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
openapi: 3.0.3
info:
title: hi
version: 0.0.1

paths:
/hi:
get:
responses:
'200':
description: OK
content:
text/plain:
schema:
type: string
enum: ["hello"]

比如以上文档就描述了这样一个服务, 当你用 GET 方法访问 /hi 接口时

1
GET /hi

就会得到一个 body 为 hello 的响应

1
2
3
4
HTTP/1.0 200 OK
Content-Type: text/plain

hello

接下来我们介绍如何在 OpenAPI 中描述一个接口, 详细文档请移步: 编写 OpenAPI