• 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。

  • 相关阅读:
    Linux(CentOS)下squid代理服务器配置-五岳之巅
    用类实现二叉树
    django--02 模板的使用
    django --01 helloworld样例入门
    微指数爬虫
    celery_01 _celery安装启动
    python多线程几种方法实现
    crontab问题处理
    python可视化--matplotlib
    python网页爬虫--京东家电版块
  • 原文地址:https://www.cnblogs.com/Henry-ZHAO/p/12725185.html
Copyright © 2020-2023  润新知