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

15

我有Visual Studio 2008和64位Windows7。

我正在使用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>

怎样做到呢?


1
创建一个项目。将文件添加到项目中。不过,使用命令行会更好。 - David Heffernan
那是因为你没有正确设置环境变量。 - David Heffernan
1
使用lib.exe来构建.lib文件。 - James McNellis
1
请编辑您的问题并将信息放入问题中,而不是作为评论。 - Thomas Matthews
只是提供信息,微软编译器允许您直接链接到 .obj 文件,就好像它们是 lib 文件一样。您可能不需要它们作为库。 - VoidStar
@VoidStar,是的,我知道。 - user366312
2个回答

28

是的,你可以这样做,基本上就像你已经写的那样。

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)(每个用户或系统范围内),也可以通过命令行指定,通过/I/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,很可能是因为您的用户没有足够的权限在“Program Files”目录中编写文件。否则,可能是由于针对您的目标使用了不正确的工具链(x86 vs. x64)而引起的错误。

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


是的,你说得对,那是关于权限和工具选择的问题。在我授予你赏金之前,你能告诉我如何部署lib文件,这样我就不需要像#include "graphics.h"那样包含C++头文件了吗??相反,我想写#include <cgraphics>,或者至少是#include <graphics.h> - user366312
1
@匿名。我不确定你的意思是部署库文件。头文件在编译时需要,在构建过程中需要库文件进行链接,而不是在目标机器上运行时需要。动态链接库(dll)将在运行时需要。头文件通常只包含库或dll中所需的定义(基本上这将是类和函数声明,而不是任何代码)... - Niall
1
如果您需要分发lib以供其他人构建dll,那么导入lib包括足够的代码链接到exe以加载dll并修复函数指针。 ""<>形式的include之间的区别在于预处理器如何定位头文件。 <>查找包含路径,而""查找本地文件-文件名实际上并不重要-这只是按照惯例。如果分发lib和头文件进行构建,则<>可能更好... - Niall
1
MSVC 包含一个 #pragma(lib, "mylib.lib") 指令,有助于链接,但它等效于将 lib 添加为链接器参数。这与 C# 程序集等完全不同,因为它们本质上没有直接相当于 lib 文件的东西。 - Niall
我的意思是,我希望graphics.lib和graphics.h在路径和#include指令方面像其他标准C++库一样运作。 - user366312
显示剩余2条评论

1
现代的 C++ 编译器会嵌入它所需的库信息。对于 Visual Studio,.obj 文件会包含其所依赖的 C++ 库的引用(/MT /MD /MTd /MDd),这些库具有稍微不同的实现,且相互不兼容。唯一的选择是拥有源代码,或为每个支持的构建模式准备多个 .obj 文件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接