同时将一组函数编译为.LIB和.DLL

Compile a set of functions to .LIB and .DLL at the same time

本文关键字:编译 函数 LIB DLL 一组      更新时间:2023-10-16

有什么预处理器技巧或东西可以让你在编译一组函数的同时编译lib和dll版本?

编译器不必知道你是在制作静态库还是动态库——它只需要制作对象文件。

然后,您可以获取这些对象文件,并将它们传递给库管理器(创建静态库)或链接器(并创建共享对象/DLL),是的,只要您使用链接器定义文件来控制DLL导出,您就可以对相同的对象文件执行这两种操作。

使用Visual Studio的一种方便方法是设置一个依赖于静态库的DLL项目,并为该依赖项选择"使用库依赖项输入"选项,以确保所有全局对象都包括在内,而不仅仅是那些在导出时定义在同一编译单元中的对象。然后,这些文件将只编译一次,但用于构建两个库。(当然,如果你遇到全局对象的问题,你的静态库很可能会被其他用户破坏。)

我不确定如何在Visual Studio中实现这一点的细节,但基本上,您只需要设置两个构建产品,它们使用相同的源代码构建,但具有不同的构建设置,例如启用/禁用dll中使用的declspec()属性的宏。

我认为在VisualStudio中,这可能表现为在您的解决方案中有两个项目。

据我所知,您需要创建两个共享相同源文件的独立项目。并在构建或调用动态库时,使用预处理器符号(如_DLL)限定要公开的引用,用空替换静态库或用DLL_export/DLL_inport。

由于库/DLL选项是每个配置的,并且单个项目可能有多个配置,您可以通过添加(例如)static-debugdynamic-debug等来实现这一点。这与CRT的处理方式类似,有静态和动态,有调试和不调试,过去有线程和不线程。

为了做到这一点,你需要使用配置管理器为你的项目添加额外的配置,然后你可以进行批量构建并选择你喜欢的任何组合。

如果项目/配置本身(而不是全局项目或拆分属性文件)中有许多自定义设置,则可能需要使用文本编辑器来复制现有配置并重命名它们。

输出静态库或动态库不依赖于编译器。这是链接器的工作。编译器生成.obj文件,这些文件由链接器链接到(当条件满足时,例如您需要.exe的入口点)您想要的文件。

具体来说,MS链接器link.exe有几个输出标志:

no flag: .exe is produced;
/LIB: static library .lib produced;
/DLL: dynamic library .dll and import library .lib produced;

/DLL的情况下,您还希望用__declspec(dllexport)装饰导出的函数/类,因此链接器将把它们放在导入库中。另外,请注意,静态库和导入库是不等价的,尽管它们都有.lib扩展名。链接器还可以生成其他文件:这里有链接到MSDN文章的link.exe选项。

EDIT:正如Ben所指出的,link.exe /LIB真正调用lib.exe作为静态库。运行link /LIB收益率(Windows SDK 7.1 SP1):

D:ProgramsWindows SDK 7.1>link /lib
Microsoft (R) Library Manager Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.
usage: LIB [options] [files]
   options:
      /DEF[:filename]
      /ERRORREPORT:{NONE|PROMPT|QUEUE|SEND}
      /EXPORT:symbol
      /EXTRACT:membername
      /INCLUDE:symbol
      /LIBPATH:dir
      /LIST[:filename]
      /LTCG
      /MACHINE:{ARM|EBC|IA64|MIPS|MIPS16|MIPSFPU|MIPSFPU16|
                SH4|THUMB|X64|X86}
      /NAME:filename
      /NODEFAULTLIB[:library]
      /NOLOGO
      /OUT:filename
      /REMOVE:membername
      /SUBSYSTEM:{BOOT_APPLICATION|CONSOLE|EFI_APPLICATION|
                  EFI_BOOT_SERVICE_DRIVER|EFI_ROM|EFI_RUNTIME_DRIVER|
                  NATIVE|POSIX|WINDOWS|WINDOWSCE}[,#[.##]]
      /VERBOSE
      /WX[:NO]