#学习自用#
库
库通常包含两个部分,包含目录(includes)和库目录(library),包含目录是一堆头文件,这样就可以使用预构建的二进制文件中的函数;库目录中就有那些预构建的二进制文件中的函数。
静态库
静态库是在编译时将库的代码和数据直接链接到目标程序中,生成一个包含所有代码和数据的可执行文件(.exe),这是装入时链接。静态链接在技术上更快,但是会导致源码体积变大,并且一旦发生修改就要重新编译。
这里说一下我遇到的一些问题,一开始,我按以下步骤设置好后,依旧调试报错,无法解析外部函数glfwInit等等一堆erro,我以为是编译器版本跟静态库不匹配(我用的VS2010但是能下载的GLFW库最早版本是2013的),之后我换了VS2022也使用了相应的GLFW库但是依然报错,这时VS报错中提示了解决方案平台的问题,要链接到这个库,解决方案平台需设置成x86。
首先在解决方案目录下创建一个名为dependencies的文件夹。
在dependencies文件夹中创建一个GLFW文件夹,并将下载的库中的include和lib文件夹复制到GLFW文件夹中,lib的选择应该于编译器版本相同或者接近。
右键点击helloworld项目,点击属性,在C/C++下的常规中设置附加包含项目,这个地方要设置include这个文件夹所在位置,路径可以使用宏$(SolutionDir),这个表示的是解决方案的路径。然后点击确定。
之后便可以在项目中引用头文件#include"GLFW\glfw3.h", glfw3.h中是一大堆函数的声明,但是想要使用还需要函数的定义。
右键点击helloworld项目,点击属性,找到链接器下的常规,在附加库目录中输入glfw3.lib的路径。
在输入里添加附加依赖项glfw3.lib
设置完毕后这串代码即可通过调试。
#include<iostream>
#include"GLFW/glfw3.h"
int main()
{
int a = glfwInit();
std::cout << a;
std::cin.get();
}
动态库
动态库是在运行时被链接的,你可以在选择程序运行时装载动态库;或者在程序启动时加载dll文件,这是动态链接库。
操作大部分都与链接静态库相同,这里不再赘述,只将一些不同的部分展示出来。
项目属性->链接器->输入->附加依赖项->将glfw3.lib替换成glfw3dll.lib
复制glfw3.dll到可执行文件(HelloWorld.exe)所在的文件夹中。
这段代码可以运行,说明我们成功链接到了动态库。
#include<iostream>
#include"GLFW/glfw3.h"
int main()
{
int a = glfwInit();
std::cout << a;
std::cin.get();
}
创建与使用库(多项目)
右键点击解决方案选择添加,可以在原有的基础上添加新的项目。Game将成为可执行文件,在其属性中设置常规属性->配置类型为应用程序(.exe);Engine要静态链接,在其属性中 1.平台设置为所有平台 2.设置常规属性->配置类型为静态库(.lib)。
在Game项目下新建一个src文件夹,在里面添加Application.cpp
在Engine项目下新建一个src文件夹,在里面添加Engine.cpp,Engine.h 设置好后测试一下是否可用。
Engine.h
namespace engine {
void PrintMessage();
}
Engine.cpp
#include<iostream>
#include"Engine.h"
namespace engine {
void PrintMessage()
{
std::cout << "Hello World!" << std::endl;
}
}
Application.cpp
#include"Engine.h"
#include<iostream>
int main()
{
engine::PrintMessage();
std::cin.get();
}
在Application.cpp中无法直接引用Engine.h,因为他们不在一个项目中。点击Game项目的属性-> C/C++ ->附加包含目录,添加engine源目录。
虽然头文件已经包含进来了,但是我们还没有链接到静态库,Application还无法运行,右键点击Engine项目选择生成,在输出中可以看到生成的Engine.lib的路径。
要静态链接到Engine.lib可以参考静态库里提到的步骤,这里尝试使用一下添加引用,右键点击Game->添加->引用->项目->勾选上Engine->确定。这样就完成了静态链接,Application.cpp已经可以运行了。
添加引用的好处: 1)如果Engine改名成其他,不需要重新在项目属性里设置输入文件。2)Engine内部如果发生变化比如修改代码之类的,不需要手动去重新生成Engine.lib。