【问题标题】:How simplest to reference a static library from Visual Studio 2017?从 Visual Studio 2017 引用静态库有多简单?
【发布时间】:2018-03-05 20:48:28
【问题描述】:

我们的产品需要将静态库 (.lib) 文件作为供应商 API 的一部分进行链接。

我为 API 定义了一个项目,它提供了许多函数和类,并生成了一个 .lib 文件。

但要让该 .lib 链接并被客户端使用,它还需要链接到供应商提供的这个静态预提供的 .lib。

所以依赖树是:

我的应用程序 -> API Wrapper 库 -> 静态库

我可以简单地告诉 VS 我的应用程序依赖于 API Wrapper Lib - 因此我的应用程序将链接到由 API Wrapper Lib 生成的 .lib 文件。但它无法链接到供应商的静态库文件。

在我的应用程序的链接器设置下,我可以添加“附加依赖项”并将“Static.lib”命名为依赖项 - 然后添加“附加目录”并指定该静态库所在的文件夹。

这行得通。

我可以交替使用:

      #pragma comment(lib, "static.lib")

在 My App 引用的 API Wrapper Lib 的主标头中。这消除了我的应用程序中对“附加依赖项”设置的需要。但是,除非我仍然指定“其他目录”来命名“static.lib”所在的文件夹,否则这将不起作用,即使它与已经依赖的 API Wrapper Lib 位于同一个文件夹中。

我的问题是:有没有一种更简单的方法来设计 API Wrapper Lib,以便它在自身中嵌入 static.lib,或者自动告诉链接器“嘿,当人们链接我的 .lib 时,请确保你也查看” static.lib" 来解决任何缺失的符号"

或者类似的东西..

#pragma comment(lib, ...) 很酷 - 但除了告诉它“您的链接依赖于包装器库”之外,我仍然必须通过对包装器文件夹的特殊引用来污染 My App 项目。

似乎是多余和混乱的 - 设置一件事总是更好 - 最好由包装库设置,以便最终处理所有事情 - 客户端只需要包含并指定对一件事的依赖关系。

救命!

【问题讨论】:

  • 我不知道以下是否仍然可行(找不到那么快),但在过去,可以通过将外部库指定为输入文件将其包含在另一个库中对于 LIB 命令。您可以通过将“static.lib”作为 wrapper-lib 的源文件来尝试此操作(添加现有项目并从某处选择 .lib)
  • 刚刚对依赖于第二个库的 1 个库的 1 个应用程序进行了小测试。带 1 个备注:在 1 个解决方案中使用这 3 个项目,并从一个到另一个的附加引用。但是当我从解决方案中删除项目第二个库时,链接失败! ?
  • 抱歉,无法完成这项工作。尝试了几种设置(编译器和/或图书管理员),但链接一直失败。
  • 您一般都知道某些东西已经被链接以使您的代码工作,但您不知道他决定将 .lib 文件放在哪里。所以#pragma comment 是给你的,但是 Project > Properties > Linker 是给他的。自定义项目模板可能会有所帮助,但通常不支持强制源代码管理映射。请记住,提供静态库是一项永远不会完成的工作,您需要为所有编译器版本提供所有风格。提高程序员的意识,让他选择合适的人是明智的。
  • 我偶然发现了这个 - 它可能通过组合库提供解决方案:stackoverflow.com/questions/2157629/…

标签: c++ visual-studio visual-studio-2017 static-libraries static-linking


【解决方案1】:

与所有“最佳”问题一样,我无法确定我的解决方案是否“最佳”——只能说它是“实用的”并且比我提出的任何其他问题都更能满足我的要求。 em>

基本上,我决定使用编译指示来告诉链接器“链接到以下文件”,并且我已经包含了它的相对路径。

这意味着我声明知道该库文件相对于需要使用它的客户端项目的位置。这可能不适合您的情况?但如果是,这确实有效。

我也可以简单地将这个文件的确切位置拼写为绝对路径。这消除了我需要标准化客户端项目与这个“注入”静态库的包装 API 库的关系,但引入了对绝对路径的需要,这意味着这个包装库不能移动。

无论哪种方式都有一些限制,有些不太理想。

如果我有办法从编译器以宏形式获取当前项目的路径,那我就太好了!我可以使用当前的绝对路径来准确地给我我需要的东西。唉,我看不到从 MS Visual Studio 获得它的方法。具有完整路径的当前文件是可用的 - 但是如何在预处理器时削减到该字符串的路径部分?这超出了我的技能范围。

因此,我的解决方案意味着客户端项目只需要对我的 API 包装器库的依赖,以及该库的主标头中的这一行:

 #pragma comment(lib, "..\\3rd Party\\Wrapper API Library\\static.lib")

正如我所说,与必须向每个客户端项目添加“附加库目录”和“附加依赖项”字段相比,它并不完美,但功能性和合理的改进。

这意味着如果我有两个这样的包装器,并且希望在它们之间切换,我只需要更新我想要包含在我的客户端项目中的包装器,仅此而已。

更满足!

如果有人有办法从预编译器(宏阶段)获取项目路径或文件路径 - 请分享。然后这可能基本上是完美的。

【讨论】:

    【解决方案2】:

    用户@evpo 加了这个answer here,看起来更优雅了。

    他的回答很糟糕,我在这里全文引用:

    或者在项目属性中链接库依赖项 是在 Visual Studio 中链接库的另一种方式。

    打开要合并的库(X)的项目 其他图书馆。添加您想要与 X 结合的其他库 (右键单击,添加现有项目...)。转到他们的属性并制作 确定 Item Type 是 Library 这将包括 X 中的其他库 好像你跑了

    lib /out:X.lib X.lib other1.lib other2.lib

    【讨论】:

    • 这个答案让我发疯的是,这已经是我的 Wrapper API 库的配置方式。然而,我遇到了 static.lib 中缺少的链接符号。但我一定有其他问题,因为这对我来说非常有效! (去图!)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-27
    相关资源
    最近更新 更多