最近因为项目需求,需要在 Windows 下开发一个 C++ 项目,博主之前都是在 Linux 上开发的,突然转到 Windows 多少还是有点不适应的。本次使用的 IDE 是 Visual Studio,之前有简单使用过,但是很多都忘记了,故此做个记录,方便下次查看。
本文主要针对 Visual Studio 2017 的安装和项目配置进行简单的分享,若有问题欢迎各位看官批评指正!!!
Visual Studio 是什么?
Visual Studio(简称 VS)是美国微软公司的开发工具包系列产品,是一个集成的开发环境,相对来说比较完整,它包括了整个软件生命周期中所需要的大部分工具,如代码完成工具、编译器、图形设计器、UML工具、代码管控工具、集成开发环境(IDE)等等,以简化开发人员构建应用程序的过程。通俗的讲,是一款编译器。
要注意的是,它虽然和 Visual Studio Code 名字非常相近,但两者完全不是同一个东西!!!
Visual Studio Code (简称 VSCode)是美国微软公司开发的一个项目,是一款现代化开源的、免费的、跨平台的、高性能的、轻量级的代码编辑器。通俗地讲,它是一款超级的文本编辑器。
参考自:Visual Studio和Visual Studio Code(VSCode)的区别及如何选择
为什么要学习安装和配置 Visual Studio?
为了项目需求,需要在 Windows 下面开发 C++ 项目
怎么去安装和配置 Visual Studio?
博主主要参考:VisualStudio2017下载与安装教程详解
软件:Visual Studio 2017 Community
官网下载地址:https://visualstudio.microsoft.com/zh-hansda/vs/older-downloads/
网盘下载:Baidu Driver【pwd:1234】注:博主安装的 Visual Studio 2017 版本属于老版本了,大家务必根据自己的实际情况选择,另外每个版本提供三种选择:Community(社区版,对学生、开源贡献者和个人免费)、Professional(专业版,适合小型团队)、Enterprise(企业版,适用于任何规模的团队)
1. 鼠标点击【Visual Studio2017(64bit)】压缩包解压
2. 双击打开解压后的文件夹,鼠标点击【vs2017】选择【以管理员身份运行】
3. 点击继续
4. 软件下载及安装中(请保持电脑连接网络)
5. 勾选【使用 C++ 的桌面开发】(根据自己的需求勾选,博主自身只需要做 C++ 开发,右边是该选项的插件根据自己的需求选择安装,博主未做修改)
6. 点击【单个组件】栏,如果有不想安装的插件或者想安装的插件,分别是取消勾选和勾选即可(博主未做修改)
7. 点击【语言包】栏,一般选择默认即可,默认一般为【中文】
8. 点击【安装位置】(点击"…"可更改软件安装位置,建议不要安装在C盘,可以在D盘或其它磁盘下新建一个 “vs2017” 文件夹。注:安装路径中不能有中文),取消勾选【安装完成后保留下载缓存】,在右下角点击【安装】。
9. 下载安装中
10. 安装完成,点击右上角【X】退出
11. 点击【以后再说】
12. 选择自己喜欢的颜色主题,点击【启动 Visual Studio】
13. 创建桌面启动快捷方式方法:点击桌面左下角【开始】图标,点击【所有应用】 → \rightarrow → 找到并拖动【Visual Studio 2017】图标到电脑桌面
至此,Visual Studio 2017 安装成功,接下来我们来看下如何使用 Visual Studio 进行项目开发。
目的:利用 Visual Studio 2017 创建一个新项目,输出 “Hello World”
1. 点击桌面上的 Visual Studio 2017 快捷方式,然后点击【新建项目】下面的【创建新项目】
2. 点击【空项目】,项目名称和项目存放位置可自行修改,点击确定
OK!创建完了新项目我们先不着急写程序,先分析一下整个界面,
首先最上面就是我们的菜单栏,然后右边是我们的解决方案资源管理器,它是 Visual Studio 集成开发环境(IDE)中的一个面板,它用于显示和管理项目和解决方案中的文件、文件夹、引用等各种资源,我们就在这里添加我们的 C++ 文件,右下角就是关于项目的一些属性,比如项目文件的路径、根命名空间等
现在说明下 Visual Studio 解决方案中的各个部分含义:(from chatGPT)
引用(References):在这个部分,你可以添加对其他项目或外部库的引用。这些引用可以是项目内的其他项目,也可以是外部的库,它们可以是编译时链接的依赖项。
外部依赖项(External Dependencies):这个部分列出了项目所依赖的外部库或其他项目。你可以在这里设置如何查找和链接这些依赖项,以确保项目能够正确地编译和运行。
头文件(Header Files):这里包含了项目中的头文件(.h 或 .hpp 文件),这些头文件通常包含了类、函数和变量的声明。头文件的内容可以被多个源文件共享,因此它们通常包含接口定义。
源文件(Source Files):这个部分包含项目中的源代码文件(.cpp 文件)。这些文件包含了实际的类实现、函数定义等。
资源文件(Resource Files):这里包含项目所需的资源文件,如图标、位图、字符串等。这些资源文件可以用于项目的用户界面和其他功能。
然后整个界面中还有两个地方值得我们重点关注,一个是编译模式选择,另外一个是编译平台选择,下面我们就具体说下该如何选择
Copy自:Visual Studio中Debug与Release以及x86、x64、Any CPU的区别
关于编译模式,在 Visual Studio 中编译模式有 2 种:Debug 与 Release。这也是默认的两种方式,在新建一个项目的时候,就已经存在这两种模式供选择。
Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序
Release 通常称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。
这点类似于 GCC 编译器中的 -g、-O 选项,在开发阶段我们会启动 -g -O0 选项以方便调试,而在发布生产环境时会启动 -O3 选项进行优化
一般都是用 Release 来打包发布程序,因为 Release 做了更多的优化,运行速度更快,适合在项目完成后部署,另外,Release 打包出来的程序文件也相对来说会小一些。而 Debug 模式更适合在开发调试的时候使用。即:开发调试的时候使用 Debug 模式,打包发布程序用 Release 模式。
关于编译平台,它们之间最直接的区别就是:x86 平台编译出来的 .exe(可执行文件)或者 .dll(动态链接库)都是 32 位的,x64 平台编译的则是 64 位的
如果你的项目主程序(编译出来是 .exe 文件的)是 x86 平台下编译的,而它所依赖的一个项目(或动态链接库)是 x64 位平台编译出来的,则会提示 “未能加载文件或程序集…或它的某一个依赖性,试图加载格式不正确的程序” 之类的错误。这是因为 32 位程序不能加载 64 位的 dll,更不能调用其中的类、方法和对象等。
反之,若主程序是由 x64 平台编译出来的,而 dll 是 x86 的也是不行的!
因此,基本可以确定一点:dll 和主程序的生成平台只要一致就可以
那怎么查看自己的电脑是 x86 系统还是 x64 系统呢?
我们可以右键点击【我的电脑】的属性,在【系统类型】中可以看到,如下图所示:
可以看到博主的电脑是 64 位操作系统,基于 x64 的处理器
接下来我们再来看下创建了一个新项目后文件夹多出了哪些文件
F:\project\test
├─test
│ ├─test.vcxproj
│ ├─test.vcxproj.filters
│ └─test.vcxproj.user
└─test.sln
Visual Studio 在创建项目时会自动生成一个默认的文件夹结构,其中包括解决方案文件、项目文件、过滤器文件和用户项目文件。生成多层文件夹结构的原因是为了更好地组织和管理项目的相关文件,避免混乱。
可以看到 test 项目文件夹下又包含了一个 test 文件夹和一个 test.sln,而下属的 test 文件夹下又包含了三个文件,在 Visual Studio 项目中,.sln 文件是解决方案文件,.vcxproj 文件是项目文件,而 .vcxproj.filters 文件是用于组织项目结构的过滤器文件,.vcxproj.user 文件包含了特定用户的项目设置。让我们来看一下这些文件的作用:(from chatGPT)
.sln 文件(解决方案文件): 解决方案文件包含一个或多个项目,可以将多个项目组织在一个解决方案中。解决方案文件本身不存放项目文件,而是引用项目文件的路径和信息。一个解决方案可能包含多个项目,这些项目可以是不同类型的应用程序、库、测试等。
.vcxproj 文件(项目文件): 项目文件是特定类型的项目的配置文件,例如 C++ 项目就使用 .vcxproj 文件。它包含了项目的编译、链接和部署等设置。通常,一个解决方案中会包含一个或多个 .vcxproj 文件,每个文件对应一个项目。
.vcxproj.filters 文件(过滤器文件): 过滤器文件用于组织项目中的文件,将源代码、头文件、资源等文件按照文件夹结构进行分类,以便在 Visual Studio 中更好地组织和浏览项目文件。
.vcxproj.user 文件(用户项目文件): 用户项目文件包含了特定用户对项目的一些自定义设置,例如编译器选项、调试选项等。这些设置是个人化的,不会与其他人共享。
在 Visual Studio 中,解决方案文件所在的文件夹通常作为顶层文件夹,其中包含项目文件和其他辅助文件。你看到的多层文件夹结构只是为了更好地组织和管理项目文件,不同的文件承担不同的角色。
在一个解决方案(.sln 文件)中,可以包含多个项目(.vcxproj 文件),每个项目都可以有自己的 main.cpp 或其他入口文件。解决方案文件的作用是将多个项目组织在一起,而每个项目可以是不同类型的应用程序、库等。因此,一个解决方案可以包含多个项目,每个项目都可以有自己的独立的入口文件。
OK!简单分析完了以后,我们来编写一个 main.cpp 程序文件用于输出 “Hello World”,在正式编写代码之前我们选择 Debug 编译模式,x64 编译平台,我们往下继续
3. 右键点击解决方案 test 的源文件 → \rightarrow →添加 → \rightarrow →新建项
4. 创建 main.cpp 源文件,点击【C++文件(.cpp)】,修改名称,点击添加
5. 编写代码
6. 执行,点击菜单栏中的【调试】然后点击【开始执行(不调试)】,或者按 Ctrl+F5 快捷键
7. 运行效果如下
可以看到成功生成了 test.exe 可执行文件,并且终端成功打印了 “Hello World”
OK!那以上就是一个最简单最基本的项目的创建,接下来我们来看点稍微高级点的东西
我们在开发项目时经常需要使用到一些第三方库,比如 CUDA、cuDNN、TensorRT、OpenCV 等等,那接下来我们学习下如何在我们自己创建的项目中引用第三方库,我们以 OpenCV 为例,其它第三方库类似
参考自:VS2017配置 opencv 教程(超详细!!!)、一文搞定 Visual Studio 配置 OpenCV 环境
下载地址:https://opencv.org/releases/
网盘下载:Baidu Driver【pwd:1234】
博主以 OpenCV-4.5.0 为例,点击 Windows 后即可完成下载,
由于是外网访问下载速度可能比较慢,记得开代理,这边提供博主下载好的几个不同版本的安装包,Baidu Driver【pwd:1234】
我们把下载好的安装包移动到指定文件夹下,建议大家建立一个公共的文件夹,专门用来存放第三方库文件,方便后续不同项目开发的指定,博主将 OpenCV 安装包移动到了 F:\project\lean 文件夹下,在 lean 文件夹下后续可以存放各种各样的第三方库,包括 CUDA、cuDNN、TensorRT 等
下载好的文件是一个 .exe 可执行文件,我们直接双击点击 Extract 提取文件即可
耐心等待一段时间后,在 lean 文件夹下面会多出一个 opencv 文件夹,这个就是我们安装好的 opencv
那你可能会好奇,这样就安装完 opencv 了吗?这不就相当于下载了一个压缩包然后解压吗?
那其实没错,这样就把 opencv 安装完成了,后续的都是一些环境配置的问题,与 Linux 下面编译 opencv 不同的是在 Windows 下,OpenCV 提供了预编译的二进制发行版(直接提供编译好的动态库),你只需要下载压缩包并解压,然后进行相应的环境配置即可使用。
而在 Linux 下,操作系统的软件包管理方式通常是基于源代码的编译和安装。这意味着大多数软件包(例如 OpenCV)在 Linux 下需要从源代码编译生成可执行文件和库(手动编译)。这种方式允许用户根据自己的需要进行定制和优化,并且能够适应不同的 Linux 发行版和体系结构。
在 Windows 下使用 OpenCV 时,我们还需要将 OpenCV 的 bin 目录添加到系统环境变量中。这样做的目的是为了让操作系统能够找到 OpenCV 的动态链接库(DLL)文件。这样,当你在你的项目中使用 OpenCV 时,系统就可以在环境变量中查找到所需的 DLL 文件并加载它们。而不至于说找不到对应的 DLL 库文件而报错
首先我们要确保下我们需要添加的 bin 文件的路径,bin 文件存放在我们刚才下载好的 opencv/build/x64 文件夹下,点开这个文件夹你会发现存在 vc14 和 vc15 两个不同的 bin 文件路径,我们该选择哪个呢?
这其实涉及到 Visual Studio 的版本。这两个版本分别对应着不同的 Visual Studio 编译器版本,具体来说:
vc14:这是指使用 Visual Studio 2015 编译器编译的版本。
vc15:这是指使用 Visual Studio 2017 或更新版本的编译器编译的版本。
选择哪个版本取决于你使用的 Visual Studio 版本。如果你在使用 Visual Studio 2015,那么应该选择 vc14 版本的库。如果你在使用 Visual Studio 2017 或更新版本,那么应该选择 vc15 版本的库。
那博主的 Visual Studio 是 2017 版本的,因此选择 vc15 版本,那最终博主要添加的 bin 文件的完整路径就是 F:\project\lean\opencv\build\x64\vc15\bin
接下来我们就是要把上述的路径添加到系统环境变量中
【找到此电脑】 → \rightarrow →【右键属性】 → \rightarrow →【高级系统设置】 → \rightarrow →【环境变量】 → \rightarrow →【系统变量Path】 → \rightarrow →【编辑系统变量Path】 → \rightarrow →【新建把路径复制进去点击确定】
OK!以上就是 OpenCV 系统环境变量的配置,也就是在系统变量路径中添加了一个 OpenCV 的 bin 路径
我们接下来就去看看项目中该如何去配置,我们拿之前创建的 test 项目为例,如果我想要在这个项目中使用 opencv 读取一张图片并显示,我该如何做呢?
上来我们就直接来编写程序,首先需要包含 opencv 的头文件 opencv2/opencv.hpp
可以看到编译器提示头文件找不到,那这是因为我们并没有告诉编译器去哪里找 opencv,也就是没有配置 opencv 的头文件目录,接下来我们配置下 opencv 的头文件目录
右键点击解决方案 test,点击属性(或者直接点击上面的小扳手),
点击进来后可以看到该项目(test)的属性页面,那么这个属性页面是非常非常重要的,你可以在这里配置这个项目的所有东西,比如项目所依赖的头文件目录、库文件目录、链接的动态库等等,你可以把它理解为 Linux 上面的 CMakeLists.txt 或者 Makefile 文件
那一进来其它的先不看,我们先来看下上面的两个配置,一个是编译模式的选择,另外一个是编译平台的选择,那你可能会疑问,前面的 活动 又是什么意思呢?
那在 Visual Studio 项目的属性页面中,带有 “(Active)” 标签的选项是指当前处于活动状态的配置。这意味着在你进行项目编译、调试、运行等操作时,所使用的配置选项是标记为 “(Active)” 的配置。
那么当前我们是在 x64 平台下的 Debug 编译模式,因此就先配置 x64 和 Debug。那你可能会好奇,Debug 和 Release 编译模式下项目所依赖的头文件、库文件不是都一样吗?为什么不选择 “所有配置” 一起配置呢?
那之前有提到过 Debug 和 Release 的区别,为了调试方便在 Debug 模式下我们是没有进行优化的,而在 Release 模式下我们是使用了优化的,想必你也猜到了,opencv 官方提供的 opencv 动态库其实是存在 Debug 和 Release 两个的,在不同编译模式下我们应该选择不同的动态库,这点后面会提到,因此建议还是分开配置为好
那我们先来解决头文件目录问题,我们先找到我们下载的 opencv 安装包的头文件目录,它在 opencv\build\include 下面,对于博主的完整路径是 F:\project\lean\opencv\build\include
找到了 opencv 安装包头文件的路径,我们来配置头文件目录,在打开的项目属性页中,在【VC++目录】中的【包含目录】编辑添加 OpenCV 的 include 文件夹路径:
F:\project\lean\opencv\build\include
点击确定可以看到【包含目录】中多了 opencv 的头文件路径,如下图所示:
然后我们还需要在【C/C++】下面【常规】中的【附加包含目录】编辑添加 OpenCV 的 include 文件夹路径:
F:\project\lean\opencv\build\include
点击确定可以看到【附加包含目录】中多了 opencv 的头文件路径
那你可能会问,之前不是在【VC++目录】中配置了头文件目录吗?为什么还要再配置一次呢?
这是因为虽然你可能在项目属性页的【VC++目录】中配置了包含目录使得你的项目能够正常编译。但是一般来说,还是推荐在【C/C++】 → \rightarrow →【常规】中配置【附加包含目录】。这是因为在这里设置的附加包含目录会对整个项目中的源文件生效,而不需要针对每个源文件都单独设置。这样能够提高代码的可维护性,并且在项目需要扩展或修改时,更加方便管理。
此时再看代码可以发现编译器没有提示找不到 opencv 的头文件了,说明我们添加成功了
OK!头文件添加成功了我们就来把后续的代码完成,整体代码如下:
代码非常简单就是利用 OpenCV 读取一张图片然后显示,那你可能会好奇,代码中图片的路径是根据相对目录来指定的,那这个相对目录是相对谁而言的呢?
在 Visual Studio 中,相对目录是相对于项目文件所在的文件夹来指定的。项目文件通常是具有 .vcxproj 扩展名的文件,它包含有关项目的配置和设置信息。相对目录是相对于这个项目文件所在的文件夹来进行计算的。
例如,如果你的项目文件位于 F:\project\test\test\test.vcxproj,而你的图片文件位于 F:\project\test\test\workspace\Lenna.png,那么在项目中引用图片时,相对路径应该是 workspace\bus.jpg。如下图所示:
那我们直接按 Ctrl+F5 来执行,可以看到编译报错了,如下图所示:
无法解析的外部符号…,那这个问题主要是由于链接器(Linker)无法找到所需的函数的实际定义,而在代码中该函数却被引用了。
那你可能回想起来了,虽然我们添加了头文件目录,但是我们貌似并没有添加库文件目录,没有正确地链接上 OpenCV 库呀,在 Visual Studio 中,我们需要将正确的 OpenCV 库文件夹添加到项目属性的库目录,并将所需的库名称添加到项目属性的附加依赖项中。我们接下来就做这么一件事情
首先我们要找到库文件的目录,它在 opencv\build\x64\vc15\lib 下面,对于博主的完整路径是 F:\project\lean\opencv\build\x64\vc15\lib
然后我们在打开的项目属性页中,在【VC++目录】中的【库目录】编辑添加 OpenCV 的 lib 文件夹路径:
F:\project\lean\opencv\build\x64\vc15\lib
点击确定后可以看到【库目录】中多了 opencv 的库文件路径
那此时我们只是设置了库文件目录,需要具体链接的库文件还没有真正配置,我们接下来配置链接器
在我们打开的项目属性页中,在【链接器】下面的【输入】中的【附加依赖项】编辑添加需要链接的 OpenCV 库文件:
那可能你会好奇我怎么知道链接的库文件名称呢,那其实在 opencv\build\x64\vc15\lib 库文件目录下就有 .lib 后缀结尾的两个库文件,如下图所示:
上面两个库文件就是我们需要链接的 opencv 库,那你可能会问不是有 opencv_world450.lib 和 opencv_world450d.lib 两个库嘛,具体链接哪一个呢?还是说都需要添加?
那这其实是 OpenCV 库的两个不同版本,分别用于 Release(Release 模式)和 Debug(Debug 模式)构建。
在 Visual Studio 项目中,根据你的编译模式(Release 或 Debug),你需要设置链接器的库依赖项,分别链接到对应的库文件。如果在 Release 模式下编译,确保链接到 opencv_world450.lib;如果在 Debug 模式下编译,确保链接到 opencv_world450d.lib。这样可以确保在不同的构建模式下使用正确的库。
由于博主的编译模式是 Debug 模式,因此链接的是 opencv_world450d.lib 库,当你编译模式是 Release 模式时,你需要选择的是 opencv_world450.lib 库
OK,库文件路径和对应的链接库配置完成了,我们再按 Ctrl+F5 执行下
可以看到编译通过了,而且图像也正常显示了,这说明 opencv 库的使用没问题了
OK!以上就是关于 OpenCV 库的配置
上面我们详细分析了在 Visual Studio 中如何使用 OpenCV 库,下面我们简单总结下如何在 Visual Studio 中使用一个第三方库。总体可分为:系统环境变量配置和 Visual Studio 项目环境配置两部分
1. 系统环境变量配置(optional)
这一步通常不是必须的,尤其是在使用静态链接库的情况下。但对于某些库,尤其是那些提供了可执行文件的库(例如 OpenCV),可能需要将其路径添加到系统环境变量中,以便在终端中运行可执行文件时能够正确找到依赖的库文件。
2. Visual Studio 项目环境配置
2.1 包含目录添加头文件路径 【VC++目录】 → \rightarrow →【包含目录】
这是为了在编译时能够找到第三方库的头文件。这通常是必须的,因为你的源代码中会包含库的头文件以访问其函数和类。
2.2 附加包含目录中添加头文件路径 【C/C++】 → \rightarrow →【常规】 → \rightarrow →【附加包含目录】
这一步是为了告诉编译器在哪里找到你所使用的第三方库的头文件。将头文件路径添加到项目的 附加包含目录 中,确保项目的每个源文件都能找到所需的头文件。这提高了项目的可维护性,因为你不需要为每个源文件都手动设置包含路径。
2.3 库目录添加库文件路径 【VC++目录】 → \rightarrow →【库目录】
这是为了告诉链接器在哪里找到库文件。通常来说,你需要将库文件的路径添加到项目的 库目录 中,以便链接器能够找到所需的库文件。
2.4 链接器设置添加链接库 【链接器】 → \rightarrow →【输入】 → \rightarrow →【附加依赖项】
这是为了告诉链接器需要链接哪些库文件。根据你使用的库,你可能需要在项目的 附加依赖项 中添加相应的库文件名,如 opencv_world450.lib。
假设我在 Linux 上面开发了一个新的项目,后续我想在 Windows 下面开发,我该如何把已有项目添加到 Visual Studio 中继续开发呢?
这边拿一个非常简单的示例说明下,假设 Linux 下开发的项目文件目录结构如下:
src
├─common
│ ├─ilogger.cpp
│ └─ilogger.hpp
└─main.cpp
整个项目文件非常简单(为了方便说明,实际情况肯定复杂得多),只包含一个 src 文件夹存放着所有的源代码,在 src 文件夹下又包含一个 common 文件夹和一个 main.cpp 文件
common 文件夹下有 ilogger.hpp 和 ilogger.cpp 两个文件,它们其实来源于 https://github.com/shouxieai/tensorRT_Pro/tree/main/src/tensorRT/common
这两个文件是杜老师实现的,功能是为用户提供了一个日志库,该库支持多种日志级别,并提供了文件操作、日期和时间、字符串操作、颜色转换等辅助功能。此外,它还考虑了跨平台的需求,为 Windows 和 Linux 提供了特定的实现。
由于它的日志打印包含时间、文件行号非常适合调试,同时还提供了一些小工具函数,因此博主经常将它包含在自己的项目中。那具体代码实现其实并不重要,我们的主要目的还是说如何把它添加到 Visual Studio 中
main.cpp 中的内容非常简单,就是利用 ilogger 中的 INFO 函数进行 “Hello World” 打印并打印当前的时间,其代码如下:
#include
#include
using namespace std;
int main() {
INFO("Hello World");
string now = iLogger::time_now();
INFO("time now = %s", now.c_str());
return 0;
}
接下来我们重点来看如何把已有项目添加到 Visual Studio 中,首先我们在 Visual Studio 中新建一个项目 test,然后将 Linux 下所有与项目相关的文件都放在与 test.vcxproj 项目文件的同级目录下,如下图所示:
那此时你就犯难了,怎么在解决方案 test 中把 src 下面的这些 C++ 文件都添加进去呢?
明明我们把整个 src 文件夹都复制过来了,为什么在解决方案中看不到任何文件呢?
那其实是因为你还没有把它们添加到项目中去,在 Visual Studio 解决方案窗口中,文件的显示是基于项目文件(.vcxproj)的结构和内容的。如果你在 .vcxproj 的同级目录下创建了一个文件夹,并在其中添加了一些 C++ 文件,但在解决方案窗口中看不到文件的显示,是因为这些文件尚未被添加到项目中。
在 Visual Studio 中,文件需要添加到项目中,才能在解决方案窗口中正确显示和管理。这是因为解决方案窗口显示的是项目的文件结构,而不是文件系统中的实际文件结构。
那我们该如何添加呢?
我们可以点击解决方案资源管理器的小扳手的左边的小图标【显示所有文件】,然后就可以看到与 test.vcxproj 同级目录下的所有文件了,接下来我们右键点击 src,选择【包括在项目中】,如下图所示:
添加完成后再点击小图标【显示所有文件】回到之前的解决方案窗口,此时可以看到 src 文件夹下的所有文件都被包含进来了,如下图所示:
值得注意的是 Visual Studio 会将添加进来的所有 .cpp 文件全部放到源文件下,而所有的 .hpp 文件全部放到 头文件下,我们可以使用 “新建筛选器” 来创建逻辑上的文件夹结构,以更好的组织项目文件
博主还是喜欢在 Linux 下的文件目录结构,因此【右键源文件】 → \rightarrow →【添加】 → \rightarrow →【新建筛选器】 → \rightarrow →【命名common】 → \rightarrow →【把ilogger.hpp和ilogger.cpp移过来】
最终的目录结构如下图所示:
那你可能会好奇,筛选器是个啥玩意?我在这边创建筛选器移动文件会不会影响到实际的文件结构呢?
那在 Visual Studio 的解决方案中,“新建筛选器” 是一种组织项目文件的方式,类似于文件夹,但在实际的文件系统中并不会创建真正的文件夹。它主要用于在解决方案中对项目文件进行逻辑上的分组和组织,以便更好地管理和维护项目。(from chatGPT)
当你在解决方案中创建一个新的筛选器时,它会在解决方案资源管理器中显示为一个文件夹图标,但并不会在文件系统中创建实际的文件夹。你可以在筛选器下添加项目文件,这些文件实际上会存储在指定的项目文件夹内,但它们在 Visual Studio 中的展示方式更加组织化。
使用筛选器的主要好处是在项目变得庞大时能够更好地组织项目文件,使其更易于导航和维护。你可以根据自己的项目需求,将不同类型的文件、相关的代码文件等放置在不同的筛选器下。
我们点开 main.cpp 中发现头文件无法打开,如下图所示:
那这是个老问题了,在配置 opencv 的时候我们也遇到过,就是头文件目录问题
你并没有告诉编译器这个头文件要去哪个目录下找,编译器找不到当然就报错咯。因此我们需要在项目属性页的【VC++目录】 → \rightarrow →【包含目录】和【C/C++】 → \rightarrow →【常规】 → \rightarrow → 【附加包含目录】中都添加 ilogger.hpp 的头文件目录,在博主的环境中,这个路径位于 F:\project\test\test\src
我们再次回到 main.cpp 中可以看到没问题了,如下图所示:
由于这个简单的项目并不需要使用库文件,因此我们不需要配置库文件目录和链接对应的库,接下来我们按 Ctrl+F5 执行,如下图所示:
可以发现存在一些问题,那这个问题是由于 common 下面的两个文件导致的
虽然日志文件对 Windows 做了特定实现,但是可以看到还是存在一些移植问题的,那往后的具体解决方法是单纯针对于这个特定项目而言的,大家可以做简单的了解,主要是把握住前面的内容即如何把一个已有项目添加到 Visual Studio 中
OK!我们来看存在的问题,主要分为两个问题,我们一个个解决
问题1:C4996 ‘sprintf’: This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
分析:使用 sprintf 格式化字符串出错, sprintf 函数在处理字符串时存在一些安全性问题,因为它没有提供足够的保护机制来防止缓冲区溢出。为了增加代码的安全性,Visual Studio 推荐使用 sprintf_s 函数代替sprintf。
解决:错误信息中其实提到了几个解决办法,最简单的就是使用 sprintf_s 函数来替换 sprintf 函数,另外就是 使用 _CRT_SECURE_NO_WARNINGS 宏
博主在这里选择第二种解决方法,使用 _CRT_SECURE_NO_WARNINGS 宏,在项目属性页的 【C/C++】 → \rightarrow →【预处理器】 → \rightarrow →【预处理器定义】 → \rightarrow →【添加_CRT_SECURE_NO_WARNINGS 】
问题2:C4996 ‘_getsystime’: This function or variable has been superceded by newer library or operating system functionality. Consider using GetLocalTime instead. See online help for details.
分析:这个错误是由于你使用了过时的函数 _getsystime,而新的库或操作系统功能已经取代了它。建议你考虑使用 GetLocalTime 函数来替代 _getsystime。GetLocalTime 函数是 Windows API 中的一个函数,用于获取本地时间。
解决:这个需要我们小改 ilogger.cpp 中的代码,如下所示
// ===== ilogger.cpp 50行 =====
#if defined(U_OS_WINDOWS)
#define __GetTimeBlock \
SYSTEMTIME t; \
GetLocalTime(&t);
#endif
// ===== ilogger.cpp 100行 =====
string date_now() {
char time_string[20];
__GetTimeBlock;
sprintf(time_string, "%04d-%02d-%02d", t.wYear, t.wMonth, t.wDay);
return time_string;
}
string time_now() {
char time_string[20];
__GetTimeBlock;
sprintf(time_string, "%04d-%02d-%02d %02d:%02d:%02d", t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond);
return time_string;
修改完成后再去 Ctrl+F5 执行下,可以看到如下结果:
可以看到运行成功了,成功打印出了 Hello World 和当前的时间
OK!以上就是关于如何在 Visual Studio 中添加一个已有的项目
这个小节主要分享 Visual Studio 使用过程中的一些小技巧
Ctrl+K Ctrl+C 注释, Ctrl+K Ctrl+U 取消注释
Alt+↑,Alt+↓ 上下移动该行
shift+ → \rightarrow → 选择
ctrl+shift+enter 在下一行插入,ctrl+enter 在上一行插入
更多快捷键参考:快捷键大全
那你可能会好奇我们在编译执行的过程中产生的中间文件和可执行文件在哪里呢?
其实你如果仔细观察我们的项目文件夹,会发现不知不觉中多了很多其余的文件,只是我们之前都没有关注而已,其实编译产生的中间文件在 .vcxproj 的同级目录下,由于博主使用的是 Debug 编译模式,平台是 x64,那么中间文件就在 x64/Debug 文件夹下
编译最终产生的可执行文件在 .sln 的同级目录下,由于博主使用的是 Debug 编译模式,平台是 x64,那么可执行文件就在 x64/Debug 文件夹下
我们配置编译路径主要是为了防止文件污染,确保生成的中间文件和可执行文件都在我们指定的位置
我们现在希望生成的中间文件存储在 .vcxproj 同级目录下的 objs 文件夹下,可执行文件存储在 workspace 文件夹下,如下图所示:
那我们该如何配置呢?
首先先点开项目属性页,在【常规】 → \rightarrow →【输出目录】/【中间目录】可以配置对应路径
可以看到它有默认的路径,是通过一些宏定义来实现的:
$(SolutionDir):解决方案名,即 .sln 所在路径
$(Platform):解决方案平台名称,如 x86、x64
$(Configuration):当前的编译配置名称,如 Release、Debug
$(ProjectName):当前工程(项目)名称,如示例中的 test
(补充)我们可以在:项目(鼠标右键)→属性→配置属性→常规→输出目录(点击下拉箭头)→编辑→宏中看到相应名称和值的一一对应关系。
参考自:vs2017+配置工程的编译路径(输出目录和中间目录)
那么我们也可以利用这些宏定义来实现对应的编译路径指定,如下图所示:
大家写完之后可以对照下面输出的值,看是不是自己真正想要的路径
指定完成后再去执行代码后,你会发现编译的中间文件会放在 objs 下,可执行文件放在 workspace 下,清清爽爽,看起来非常舒服
本篇博客简单分享并记录了博主在学习和使用 Visual Studio 开发 C++ 项目时的一些基础知识,首先分享了 Visual Studio 的安装和创建一个新项目,然后以 opencv 库为例分享了第三方库的使用,主要是头文件和库文件路径的包含,以及链接器的库文件链接,接下来分享了一个已有项目如何添加到 Visual Studio 中,我们需要把源文件都包含到项目中,并且指定项目中所使用的头文件和库文件路径以及对应的库,最后就是博主在使用过程中的学到的一些小技巧。
由于博主也只是初学者,后续有新的发现再和大家分享吧,这次就先到这里了,感谢各位看到最后,创作不易,读后有收获的看官请帮忙点个⭐️
Visual Studio和Visual Studio Code(VSCode)的区别及如何选择
Visual Studio中Debug与Release以及x86、x64、Any CPU的区别
VS2017配置 opencv 教程(超详细!!!)
一文搞定 Visual Studio 配置 OpenCV 环境
Visual Studio快捷键大全
Visual Studio更改字体和颜色
vs2017+配置工程的编译路径(输出目录和中间目录)