如何从 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。
其他包含和库路径;
在为其他构建分发这些输出时,可能需要在目标构建中包含额外的标头和库路径。要向包含和库搜索路径添加其他位置,可以将环境变量(INCLUDE
和 LIB
)添加到(每个用户或系统范围内),但也可以在命令行上通过 @ 指定这些位置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 2013 Javascript Intellisense 同步 obj 文件夹中的文件。是不是可以从同步中排除文件夹?