如何从 Visual C++ 的 .obj 文件构建静态和动态库?

Posted

技术标签:

【中文标题】如何从 Visual C++ 的 .obj 文件构建静态和动态库?【英文标题】:How to build static and dynamic libraries from .obj files for Visual C++? 【发布时间】:2015-08-01 16:05:35 【问题描述】:

我有 Visual Studio 2008,Windows7 64 位。

我正在使用WinBGIm 图形库。

这个库提供了一些 .obj 文件。没有 .lib 或 .dll 文件。

我想将它们转换成静态 .lib 和动态 .dll 文件。

我已经复制了目录中的所有 .obj 文件:

C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\amd64

但是,以下命令不起作用:

C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\amd64>lib.exe /out:bgiout.lib *.obj
Microsoft (R) Library Manager Version 9.00.21022.08
Copyright (C) Microsoft Corporation.  All rights reserved.

LINK : fatal error LNK1104: cannot open file 'bgiout.lib'

C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\amd64>

怎么做?

【问题讨论】:

创建一个项目。将文件添加到项目中。不过命令行要好得多。 那是因为你没有正确设置环境变量。 要构建 .lib,请使用 lib.exe。 请编辑您的问题并将您的信息放入问题中,不要作为 cmets 仅供参考,Microsoft 编译器允许您直接链接到 .obj 文件,就好像它们是 lib 文件一样。您可能不需要它们作为库。 【参考方案1】:

是的,你可以这样做,就像你拥有它一样。

C:\Code\bgi\obj>lib /out:libbgi.lib *.obj

LIB (lib.exe) 用于创建静态库。 LINK (link.exe /DLL) 用于创建动态库(它创建 .dll 和导入库 .lib)。

C:\Code\bgi\obj>link /DLL /out:bgi.dll *.obj [additional libs]

使用link /DLL 命令时,需要额外的Win32 和C++ 标准运行时库(如MSVCRT.lib 和User32.lib 等以及MFC 库)。

在这种情况下;这似乎是正确的链接器参数;

C:\Code\bgi\obj>link /DLL /out:bgi.dll *.obj MSVCRTD.lib User32.lib Gdi32.lib ole32.lib Comdlg32.lib OleAut32.lib

注意:构建的目标文件是调试版本,因此这里使用的是 MSVCRTD.lib(注意 D)。使用上面的命令,我已经能够成功链接 .dll 和静态 .lib。

其他包含和库路径;

在为其他构建分发这些输出时,可能需要在目标构建中包含额外的标头和库路径。要向包含和库搜索路径添加其他位置,可以将环境变量(INCLUDELIB)添加到(每个用户或系统范围内),但也可以在命令行上通过 @ 指定这些位置987654323@和/LIBPATH如下;

cl /IC:\Code\include [additional options] main.cpp
link /LIBPATH:C:\Code\lib [additional options] xyz.lib

指南;

启动“Visual Studio”命令提示符,给定2008,在开始菜单“Visual Studio 2008 命令提示符”中应该有一个链接。此批处理文件将为 C++ 构建设置正确的环境。确保为 x86 或 x64 目标匹配正确的工具链。 导航到包含对象文件的目录。 运行您拥有的命令(如上)。

您的错误 LNK1104

我怀疑您遇到的错误LNK1104 很可能是因为您的用户没有足够的权限在“程序文件”目录中写入文件。否则,为您的目标(x86 与 x64)使用不正确的工具链可能会出错。

通常最好在您自己的目录中执行此操作;例如:“C:\Code\bgi”.

【讨论】:

是的,你是对的,那是关于许可和工具的选择。在我奖励你之前,你能告诉我如何部署 lib 文件,这样我就不需要包含像 #include "graphics.h" 这样的 C++ 头文件?相反,我想写#include <cgraphics>,或者,至少,#include <graphics.h> @anonymous。我不确定您要部署 lib 是什么意思。在构建期间的编译时需要头文件。在构建的链接时需要 lib 文件,而不是在目标机器上的运行时。运行时需要 dll。头文件通常只包含 lib 或 dll 中代码所需的定义(本质上是类和函数声明,而不是任何代码)... 如果您需要分发 lib 以供其他人针对 dll 构建,则导入 lib 包含足够的代码来链接到 exe 以加载 dll 并修复函数指针。 ""<> 形式的 include 之间的区别在于预处理器如何定位头文件。 <> 查找包含路径,"" 在本地查找文件——文件名并不重要——这只是按照惯例。如果分发用于构建的库和标头,那么<> 可能会更好... MSVC 包含一个 #pragma(lib, "mylib.lib") 指令来协助链接,但它相当于将 lib 添加为链接器参数。这与本质上没有直接等效于 lib 文件的 C# 程序集等完全不同。 @anonymous。我知道这有点长,但我希望对 C++ 构建的某些方面有所帮助?【参考方案2】:

现代 C++ 编译器将嵌入有关他们需要的库的信息。对于 Visual Studio,.obj 文件包含对它所依赖的 C++ 库的引用 (/MT /MD /MTd /MDd),这些库的实现略有不同,并且与它们不兼容。唯一的选择是为每种支持的构建模式提供源代码或多个 .obj 文件

【讨论】:

以上是关于如何从 Visual C++ 的 .obj 文件构建静态和动态库?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Visual Studio 编译器使用 cgo 构建库?

为啥我的 Visual Studio .obj 文件比输出的 .exe 文件大?

链接错误2005 Visual Studio 2008 C++

从目标文件列表 (*.o) 构建库 (lib.a) 的 makefile

如何获取 Visual Studio C++ 工具集标签

Visual Studio 2013 Javascript Intellisense 同步 obj 文件夹中的文件。是不是可以从同步中排除文件夹?