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

时间:2012-02-15 21:41:02

标签: c++ windows visual-c++ dll

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

5 个答案:

答案 0 :(得分:3)

编译器不必知道您是在制作静态库还是动态库 - 它只是制作目标文件。

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

使用Visual Studio的一种便捷方法是设置依赖于静态库的DLL项目,并为该依赖项选择"Use Library Dependency Inputs"选项,以确保包含所有全局对象,而不是只是在与导出相同的编译单元中定义的那些。然后文件将只编译一次,但用于构建两个库。 (当然,如果您遇到全局对象的问题,那么您的静态库可能会被其他消费者破坏。)

答案 1 :(得分:1)

我不确定如何在Visual Studio中执行此操作的详细信息,但基本上您只需要设置两个构建产品,这些产品构建自相同的源代码,但具有不同的构建设置,例如用于启用/禁用dll中使用的declspec()属性的宏。

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

答案 2 :(得分:1)

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

答案 3 :(得分:1)

由于库/ DLL选项是 per-configuration ,并且单个项目可能有多个配置,您可以通过添加(例如)static-debugdynamic-debug来完成此操作, 等等。这类似于处理CRT的方式,静态和动态,调试与否,以及过去的线程而不是。

为此,您需要使用配置管理器为项目添加其他配置,然后您可以进行批量构建并选择您喜欢的任意组合。

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

答案 4 :(得分:1)

输出静态库或动态库不依赖于编译器。这是链接器的工作。编译器生成.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扩展名。链接器还可以生成其他文件:这里是link to MSDN article on link.exe options

编辑:正如Ben指出的那样,link.exe /LIB实际上为静态库调用了lib.exe。运行link /LIB会产生(Windows SDK 7.1 SP1):

D:\Programs\Windows 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]