关于VS2022中C++导入第三方库的方式与问题
简单话语
这篇博文主要还是写给新进入实验室的小伙伴参考。这篇文章需要你懂得什么是第三方库,什么是头文件,什么是库文件(静态/动态),你需要事先安装好VS2022并选择按安装了C++开发环境(换言之,我认为你至少用过C++,并成功输出过hello world)。
我们开始。
首先,新建一个Cpp项目(控制台项目即可,其他项目也无所谓),右键点击项目名称(Test1)选择属性或者在VS2022工具栏选择调试标签->属性按钮打开属性页。
注意点: 在开始其他操作前请注意先进行 配置和平台选项框的选择。配置选框选定了是配置为DeBug模式还是Release模式。而平台则是选定了32位程序还是64位程序。(如果选错了会怎么样?例如如果对于32位的库选择了64位平台配置但调试时又选择的32位编译,则也许语法提示不会标红但编译时可能会报解析不到函数等错误。) |
在进入主题之前,还需要弄清楚一些前置知识。
在属性页中,存在三个重要标签目录:VC++目录、C/C++、链接器。在VC++标签中,存在包含目录和库目录。在C/C++标签-常规存在附加包含目录。在链接器-常规中存在附加库目录,输入中存在附加依赖项。很多人对此比较蒙圈。
首先,VC++目录下的包含目录和库目录是什么东西?包含目录:这个目录列表用于指定预处理器在处理#include <...>
指令时应该查找的目录。大白话就是:你include
了一个东西,你告诉我这玩意到底在哪,我去给你找来用,你不告诉我我当然找不到了。库目录:这是一系列目录,链接器将在这里寻找库文件(例如.lib
或.dll
文件)。有些第三方库只有头文件(header-only库),但是有些库你会发现他还提供了链接库文件,这时候你得告诉他链接库在哪。
然后,C/C++目录下的附加包含目录:这个设置补充了VC++目录
中的“包含目录”,允许你添加额外的目录供预处理器在编译阶段搜索头文件。这些目录仅对当前项目有效。链接器-常规页中的附加库目录:这个设置告诉链接器去哪里寻找静态库和动态链接库(.lib
和.dll
)。与VC++目录
中的“库目录”类似,但它是链接器特定的,并且可以独立于VC++目录
进行配置。
很多人一看,不对呀,这不一样的东西嘛? 如果你去搜索你就会发现很多人会告诉你包含目录和附加包含目录(库目录和附加库目录)的区别主要在于全局还是当前项目。在现代的Visual Studio版本中,C/C++
标签下的“附加包含目录”和链接器
标签下的“附加库目录”与“附加依赖项”往往足以完成第三方库的导入,而无需再配置VC++目录
,现在也更建议这么做。(如果是老项目且需要以这种形式导入,请不要自作主张瞎搞,问清同事或者学长/学姐)
最后,在链接器-输入标签页中存在附加依赖项:这个选项允许你列出项目在链接时需要的库文件的完整路径或名称。大白话:你不但得告诉我你在哪,你还得告诉我是哪一个。
总的来说:C/C++标签页和链接器标签页可以提供清晰的项目级配置控制。如果项目级的控制足以应对你的项目,则可以不去配置VC++标签目录。
好,我们进入主题。对于项目的导入,我们以Eigen和opengl为例。
整体流程:1.C/C++标签页-附加包含目录:告诉人家去哪找头文件。2.链接器-常规-附加库目录:你得告诉人家库目录在哪。3.链接器-输入-附加依赖项:你还得告诉我这库叫啥名。
对于Eigen库,下载解压后会发现他没有库文件,他将所有的实现都在头文件中做完了。此时,我们选择根目录所在位置,并将位置记录。选择附加包含目录-将头文件根文件夹加入目录即可正常使用。
对于纯头文件库的添加这样就可以正常使用。这类库的特点是它们所有的功能实现都在头文件中,这意味着你不需要任何额外的链接步骤,也不需要关心库文件的位置。
对于opengl库(opengl库有三个文件夹,即glew/glfw/glut 大家可以自行从网上下载)就没有那么容易,因为他多了一个库文件。
首先,第一件事情,准备好三个文件的头文件目录地址glew和glfw在include文件夹,那么怎么辨认呢?很简单,放头文件的就是头文件目录。放库文件的就是库文件目录。
例如include-GLFW-头文件:
比如libvc2022文件夹下全是库文件:
那既有头文件又有库文件怎么办啊(比如glut),我又分不清他是算哪个还是都算还是哪个都不算,我下的库里一堆东西又不全是我要的。 |
第一件事情:在C/C++-常规-附加包含目录添加所有需要的头文件目录:
第二件事情:准备好三个文件的库文件目录。链接器-常规-附加库目录:
第三件事情:准备好所需库名字。链接器-输入-附加依赖项:
那我怎么知道要哪些库啊,我怎么知道好端端的还要多加一个opengl32.lib,你上面都没说过. |
第四件事情:准备好所有DLL,将其复制到项目根目录下。
这是什么操作?为什么要这样?我的库没有DLL怎么办?一定要这样嘛? |
附录
这里给出一个网上抄的测试代码,就是打开一个窗口
#include <iostream>
using namespace std;
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
const GLint WIDTH = 800 , HEIGHT = 600;
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow* window_1 = glfwCreateWindow(WIDTH, HEIGHT, "Hello, friend! I'm a openGL window!", nullptr, nullptr);
int screenWidth, screenHeight;
glfwGetFramebufferSize(window_1, &screenWidth, &screenHeight);
if (nullptr == window_1)
{
cout << "Failed to create GLFW window" << endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window_1);
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
{
cout << "Failed to initialise GLEW" << endl;
glfwTerminate();
return -1;
}
glViewport(0, 0, screenWidth, screenHeight);
while (!glfwWindowShouldClose(window_1))
{
glfwPollEvents();
glClearColor(0.1f, 0.8f, 0.7f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window_1);
}
glfwTerminate();
return 0;
}
结果如下: