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。