c++宏定义、调用及编译过程等

 1 /*
 2 //c++编译器,对源文件的编译实质就是对每个cpp都分别生成.obj,包括main.cpp.
 3 但是main.cpp和其他的.cpp文件是有区别的。其他的.cpp可以直接include到各自的头文件进行编译。
 4 而main.cpp即便包含了所有的其他头文件,依然缺少main.cpp中函数及全局变量的定义,因为只能include头文件并不能include .cpp文件!
 5 因此main.cpp在编译生成main.obj时,对于这些仅有声明的全局变量和函数仅仅是占个位置。
 6 基于以上的编译过程,要想生成可执行文件,必须通过链接器,通过main.cpp中{}一行一行顺序的去查找这些函数或变量的真正定义所在的位置
 7 然后链接起来生成main.exe。这样一来,main.cpp中的程序代码就可以调用所有的在其他cpp文件定义的函数或全局变量。
 8 main.cpp中包含的头文件的功能就是给main.cpp中用到的外部的函数和变量一个声明,进而可以进行占位继续编译下去生成main.obj。
 9 
10 */
11 
12 #ifndef YOLO_V2_CLASS_HPP
13 //白色说明,此宏还没被定义过
14 //紫色说明这里是真的有效的宏定义
15 #define YOLO_V2_CLASS_HPP 
16 //可以这么理解,如果这个宏是紫色的,那么就代表这个宏在此或之前被定义了。
17 
18 //宏定义的作用范围是本文件,但是如果被定义带头文件里,此头文件又被包含,那么宏定义对那些包含此头文件的源文件都有效。
19 //这里定义了YOLO_V2_CLASS_HPP 为 "空"。
20 
21 /*以上可以防止本头文件被重复包含。我只是要用它防止重复包含,并没有其他用处,所以用空来定义,而不是一个实数。
22 可移植性好,语言特性层次的。
23 
24 */
25 /*以上的功能还可以用控制编译器的行为来防止重复包含,那就是在程序头文件前面加  #pragma once
26 效率更高,平台相关的。
27 */
28 
29 //下面是如果没有定义LIB_API才进入,说明已经定义了。
30 
31 //  #Pragma argv   是控制编译器的指令,
32 //可以控制编译器忽略哪些错误提示 argv == warning,
33 //可以告诉编译器在整个编译过程中下面的头文件只被编译一次。argv == once
34 //可以用来将一个一个对象放入一个可执行文件或对象文件。  argv == comment(),如将lib文件包含到lib库目录。
35 
36 //项目中有main函数依然可以打成dll库,因为在打库的过程中,会进行入口重定义,定义到DLLmain(中间过程中默认完成的)
37 
38 //VS中只是说库目录,其实包括静态链接库lib和动态库dll了,因此我们在调用dll时,只需要将lib和dll放到一起,然后将此目录加入到库目录中。
39 
40 #ifndef LIB_API
41 #ifdef LIB_EXPORTS
42 #if defined(_MSC_VER)
43 #define LIB_API __declspec(dllexport)
44 #else
45 #define LIB_API __attribute__((visibility("default")))
46 //这种是Mac下的写法,在window下等价于 "__declspec(dllimport)"
47 /*
48 __declspec(dllimport)有两个作用:
49 第一:在编译时有这个前缀,调用dll库中的此函数时,直接寻找到这个函数的真正内存地址,一步到位编译。
50 没有这个前缀时,一般没有问题,但是编译时先生成这些函数占位stub的obj文件。、
51 
52 第二:如果要导入到dll库中的类具有静态成员函数时,那么在调用dll库时,不加__declspec(dllimport)前缀不能使用这些静态成员函数
53 会提示"无法解析的外部符号”。
54 
55 综上,在不调用dll中类的静态成员函数时,__declspec(dllimport)不是必须的!!!
56 */
57 #include "darknet.h"
58 #include "yolo_v2_class.hpp"
59 //为什么darknet没有这个头文件和.cpp文件?  因为darknet中有main函数起作用了,有函数入口。、
60 //而dll项目,是为了将函数封装到dll中,因此要将
61 
62 #include "network.h"
63 
64 /*
65 yolo_v2_class.cpp和yolo_v2_class.hpp已经是顶层的应用了。
66 
67 yolo_v2_class.cpp的函数在daknet.src的基础上就实现了检测所有的功能。
68 其中有些函数时定义在此yolo_v2_class.cpp中的,      声明在yolo_v2_class.hpp中。
69 还有一些函数时定义在其他文件中,              通过yolo_v2_class.cpp中的头文件声明。
70 还有一些函数定义在其他cpp文件中,     通过yolo_v2_class.cpp函数的头文件中嵌套包含的头文件声明的。
71 
72 */

通过点击 解决方案和文件夹 cmake目标视图,可以很清楚的了解整个源码的结构

都包括包含文件夹——include ,  以及源程序文件夹——src。

原文地址:https://www.cnblogs.com/Henry-ZHAO/p/12725185.html