有一些预处理器技巧或者你可以在一组函数的同时编译lib和dll版本的东西吗?
答案 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-debug
,dynamic-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。
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]