专栏算法工具链【J6】工具链VP示例为什么能运行

【J6】工具链VP示例为什么能运行

Jade-self2025-03-01
92
0

1. 引言

在上一篇文章【J6】VP简介与单算子实操 中,介绍了VP是什么,并以单算子rotate为例,介绍了VP API使用方法,但对于对C不那么熟悉的伙伴,可能会有这样的疑问:一个main函数就让VP示例跑起来了?没有什么依赖吗?CMakeLists.txt没看到,xxx.h头文件也没有,甚至连怎么编译的都没写,只有main文件中的C代码,还是让人有点迷迷瞪瞪。

由于本人就是属于对C++不那么熟悉的同学,所以下面会从我的视角来介绍上一篇文章遗留的问题,如果其中有错误或表述不当的地方,欢迎评论指正。

2. 代码解读

OE/samples/ucp_tutorial/目录下的结构如下:

在vp/code/07_single_rotate目录如下:

有个感觉即可,后面会细致的解读运行起一个VP示例所依赖的文件。

2.1 main.cpp

从main.cpp看过去,内容以及解读如下:

有两处拿出来解释下:

#include "rotate.h":该文件是一个自定义头文件,用于声明函数或类,代码中调用的 single_rotate() 在 rotate.h 中被声明,并在相应的 rotate.cpp 中被实现。

int32_t main(int32_t argc, char **argv):入口函数 main(),接收两个参数:

  • argc:命令行参数个数(包括程序本身)。

  • argv:存储命令行参数的字符串数组(char*)。

2.2 rotate.h

下面看一下头文件rotate.h,代码作用:声明 single_rotate() 函数,并防止头文件被重复包含。

来了解一下这段代码能防止头文件被重复包含。

  • #ifndef(如果未定义):检查宏 VP_CODE_07_ROTATE_IMAGE_PROCESS_H_ 是否已定义。

  • #define(定义宏):如果未定义,则定义该宏,并继续处理头文件的内容。

  • #endif 结束 #ifndef 逻辑块,确保头文件仅被包含一次。

这种方式称为 头文件保护(Header Guard),用于防止头文件的 重复包含,避免 编译错误。

还是有些不太理解?详细解释一下:

  1. 什么是头文件保护:在 C/C++ 语言中,头文件(.h)是用于声明变量、函数、类等的文件。为了防止头文件被 重复包含(multiple inclusion),通常使用 头文件保护(Header Guard),其基本结构是:

  1. 为什么要头文件保护:在大型 C++ 项目中,多个 .cpp 文件可能包含相同的头文件。例如:

  • A.h 头文件

  • B.h头文件

  • main.cpp中

当 main.cpp 被编译时,它会展开 #include:在A.h中直接包含void foo();,B.h 也包含 A.h,再次引入void foo();这会导致重复声明,如果没有 头文件保护,编译器可能会报错:

当使用了上面#ifndef / #define / #endif,就可以避免这个问题,原理如下:

第一次 包含 A.h 时:

  • A_H 未定义,#ifndef A_H 成立 → 继续执行

  • 进入 #define A_H 代码块,定义 A_H

  • 头文件 A.h 正常加载

第二次 再次包含 A.h:

  • A_H 已定义,#ifndef A_H 失败 → 直接#endif,跳过整个头文件

编译器在处理头文件时会进行优化,所以头文件保护不会影响性能,为了避免 重复包含头文件 导致的编译错误,提高代码可维护性,推荐大家使用头文件保护。

最后,#ifndef 保护多个头文件需要不同的宏名,因为宏名重复,也可能导致错误,建议使用 文件名相关的宏 方便记忆排查。

2.3 log_util.h

在rotate.h中包含了log_util.h,定义了一些用于日志打印的宏,具体的代码解读可见文章:【J6】工具链VP示例中日志打印解读

2.4 rotate.cpp

该文件解读可见文章:【J6】VP简介与单算子实操
2.5 CMakeLists.txt
想了解VP示例中CMakeLists.txt的嵌套以及运行逻辑,可见文章:【J6】工具链VP示例中Cmakelists解读

2.6 build.sh

该 Bash 脚本 用于 构建 aarch64(ARM64)或 x86(PC 端)架构的项目,并支持 自动检测 gcc 版本,确保编译环境正确。

getopt 会返回一个规范化的、已排序的选项和参数字符串,存储在 GETOPT_ARGS 变量中。例如,输入:

则 GETOPT_ARGS 可能会被解析成:

希望把build.sh脚本运行起来:

到这儿,项目构建编译就完成了。

3. 程序执行

项目构建完成后,会在vp/vp_samples下准备好程序可执行的相关依赖文件

运行vp_samples/script_x86/07_single_rotate/run_single_rotate.sh脚本即可。

至此,程序完成运行。

算法工具链
社区征文技术深度解析杂谈
评论0
0/1000