Bootstrap

VS不同项目之间的引用C++

一、前言

使用 VS 写 C++ 项目,为了结构清晰、方便管理,难免会一个解决方案下有多个项目,这时就会产生一个问题:

一个项目需要引用另外一个项目中的文件

怎么实现呢?下面我将进行介绍:

【注】

  1. 以下所有演示部分使用的项目目录结构均是
    在这里插入图片描述

  2. 需求

在 项目A 中引用 项目Lib(即导入 lib.h ),以便使用其中的函数或类等


二、错误原因与解决方案

错误输出
相信你在引用别的项目文件时会出现此类错误,点击进入官方文档给出的解决方案也是很概念性的,有时还是一大堆文字夹杂着各种跳转链接。花了大量时间在文档上到头来还是没法解决问题,有种想砸电脑的感觉。下面我将介绍一些相关情况出现错误的原因以及解决方案。

如果对于涉及到的各种配置所在的位置以及作用不清楚的请先看最后的附录部分在回来看此处

1. 错误原因分析

LKN前缀的问题为链接问题,首先我们知道一个C++源文件被编译为可执行文件会经过四个过程:

  • 预处理:处理预处理指令
  • 编译:将预处理过的文件转为汇编代码文件
  • 汇编:将汇编代码文件转为目标文件 (.obj或.o)
  • 链接:链接所有 .obj,以及所需的库文件 (.lib) 生成最终的 .exe(或者.dll)

显然此类错误发生在最后一步 —— 链接。故错误的发生无非两种:

  1. 某些 .obj、.lib文件没有成功生成,导致链接器找不到对应的文件
  2. 文件成功生成了,但是链接器不知道对应的文件在什么地方,也导致找不到文件

这样思路就清晰了,第一步先检查 .obj、.lib是否成功生成,如果第一步没问题,那么就是第二步的问题 —— 项目配置信息有问题,下面针对第二步的问题提供案例演示:

【注】 出现LNK类问题时先检查第一步,再检查第二步


2. 解决方案

【注】

  • 项目的配置属性不能弄错,如果不一样请自行修改
  • 在这基础上你要清楚静态库,动态库以及应用程序的区别,不是简单修改个属性就行。

注: A的配置属性为 应用程序(.exe),B为 静态库(.lib,或者 动态库 .dll 也一样)

VS 可创建静态库项目,写法跟普通 C++ 项目一样,只不过需要包含初始项目提供的两个头文件即可(也可以创建空项目,见配置属性修改为静态库即可)这里不演示,不会的自行百度或者查阅官方文档

(1)案例演示

如果你想使得在 “#include Lib.h” 时不用写 Lib.h 所在的具体路径(#include “…\Lib\Lib.h”),请配置项目的附加包含目录 (见附录)

  • 在 A 中引用 Lib 中的头文件 “Lib.h”

在这里插入图片描述

  • 直接运行会报错

在这里插入图片描述

  • 重点在

在这里插入图片描述说明: print_lib 是 Lib 中 lib.h、lib.cpp 中的一个函数,在 lib.h 中写的是其声明,在 lib.cpp 是其定义。报错信息说明编译器不知道 print_lib 是什么,也就是说编译器只看到了 print_lib 的声明语句,定义语句没有被编译器识别。
所以如何解决就明了了,只需要让编译器知道 print_lib 的定义语句在何处。
在 VS 中,只需要简单如下添加引用即可:

(2)解决方案
  • 在 A 中引用处添加对 Lib 的应用 (推荐

此方法与 “依次配置附加库目录与附加依赖项”(见附录) 功能基本是相同的 (但是更推荐直接添加引用)

操作: 右键引用 ——> 点击添加引用 ——> 勾选所要引用的项目 ——> 确定

  • 操作1
    在这里插入图片描述
  • 操作2
    在这里插入图片描述
  • 成功运行
    在这里插入图片描述

[附录]

右键项目 ——> 点击最下面的 “属性”,即可进入属性界面

1. 配置类型

【重点】 项目版本与配置版本必须一致,项目是 Debug,配置也必须是 Debug

(1)位置
配置属性  ——>  常规  ——>  配置类型

配置类型

(2)作用

指定项目所要生成的程序类型,如可执行文件(.exe),静态库(.lib),动态库(.dll),控制台输出信息会显示输出的路径


2. 附加包含目录

(1)位置

C/C++ ——> 常规 ——> 附加包含目录

在这里插入图片描述

(2)作用

告诉编译器在编译源代码时查找项目中头文件所在的目录,配置了可简化头文件路径写法

[演示]
目录结构如下:
在这里插入图片描述

  1. 如果没有配置附加包含目录,在A中引用B中的文件必须写全此文件的路径(绝对路径或者相对路径都可以)
    (1)正确
    在这里插入图片描述
    (2)错误
    在这里插入图片描述
    在这里插入图片描述
  2. 配置的话可以简写,只写头文件的文件名即可

(1)设置A的属性的附加包含目录为所引用的B的头文件所在路径

在这里插入图片描述

(2)成功

在这里插入图片描述


3. 附加依赖项

(1)位置

链接器 ——> 输入 ——> 附加依赖项
在这里插入图片描述

(2)作用

指明项目所需的外部库文件(.lib),通常写为对应的库文件名(多个库文件名之间用 ; 隔开)(也可以指定是 .obj,比如A项目需要B项目中的 b.obj,此时附加依赖项就写为 b.obj )


4. 附加库目录

(1)位置

链接器 ——> 常规 ——> 附加库目录

在这里插入图片描述

(2)作用

告诉编译器附加依赖项的所在的目录(当然也可以指定 .obj,根据具体需求给出对应目录即可),多个目录之间以 ; 间隔

;