使用二进制文件链接外部库,选择 64 位还是 32 位二进制文件取决于目标程序位数,而非本机操作系统位数
二进制库通常包含 includes 和 library,includes 目录中存放头文件,lib 目录中存放预先构建的二进制文件,lib 文件分为两类,一种是静态库,另一种是动态库。
| 静态库 | 动态库 | |
|---|---|---|
| 链接方式 | 库会写入到可执行文件中 | 库在程序运行时动态装载 |
| 执行方式 | 仅使用可执行文件即可 | 库文件以 dll 文件形式与可执行文件一起使用 |
| 静态链接相较于动态链接更有优势,静态链接会知晓程序需要链接的函数,动态链接对程序的运行毫不知情,需要保持库自身完整,等程序装载时再补充到程序中 |
以 GLFW 库为例,需要使用二进制文件中的 includes 和 lib-vc2019,前者目录中包含.h 文件,后者目录包含动态库 glfw3.dll 和静态库 glfw3.lib
在 vs 中设置项目属性,C/C++->general->additional include directories,设置 include 文件夹的实际目录,例如 $(SolutionDir)Dependencies\GLFW\include,使用 $(SolutionDir) 宏定义可以避免他人运行路径与本机之间的差异
设置头文件路径后,可以在程序中导入外部头文件
#include<iostream>
#include"GLFW/glfw3.h"FAQ
引用头文件时,是用引号还是尖括号?
实际上没有区别
使用引号的话,会先检查相对路径,如果没有找到相对于 main.cpp 的头文件,则会找编译器检查 include 路径
当头文件存在当前解决方案中,则使用引号表示引用的外部依赖。如果不和程序一起编译,完全是一个外部依赖,则使用尖括号
仅有头文件是无法链接成功的,头文件仅声明了对应函数,但是没有函数的具体实现
#include<iostream>
#include"GLFW/glfw3.h"
//自定义glfwInit函数的实现
int glfwInit() {return 0;}
int main() {
int a = glfwInit();
}如果没有自定义函数的实现,则会显示链接错误
设置 Linker->Input->Additional Dependencies,在前面新增 glfw3.lib,如果单独使用静态库名会导致无法识别,通过配置 Linker->General->Additional Library Directories ,增加 library 目录地址 $(SolutionDir)Dependencies\GLFW\lib-vs2019
#include<iostream>
//报错Name-mangling:GLFW是一个C语言库,而C++中声明的是C++函数
int glfwInit();
//正常运行
extern "C" int glfwInit();
int main() {
int a = glfwInit();
}未引用对应头文件,则需要自行声明,对于 C 语言库的函数,需要 extern "C" 进行修饰声明
TIP
头文件通过提供声明,告诉哪些函数可以使用(可编译)
库文件通过提供定义,使得 C++程序调用函数时可以正确执行代码(可链接)