在这种情况下,我在MSDN上找不到任何有用的东西。使用Dependency Walker,在模块列表中,我看到了Console和GUI的混合使用。
编译DLL时会产生影响吗?
答案 0 :(得分:12)
此选项仅对应用程序(exe
)产生影响,而不对库(dll
)产生影响。
/SUBSYSTEM
选项指定可执行文件的环境。子系统的选择会影响入口点符号(或入口点) 函数)链接器将选择。
这不会影响具有自己的(可选)entry point。
的库CyberShadow评论后的其他信息:加载DLL时,子系统字段本身似乎被忽略。 This article about CSRSS说(强调我的):
此外,每个进程都与一个特定子系统相关联; 此属性由链接器设置(在编译期间 过程),并驻留在以下PE结构字段中:[...]
答案 1 :(得分:2)
我下面的答复只是一些发现。
我试图在VS2015中创建以下类型的项目:
以下是其完整的链接选项:
Win32控制台应用程序项目
/ OUT:“ C:\ Temp \ ConsoleApplication3 \ Debug \ ConsoleApplication3.exe” /清单/ NXCOMPAT /PDB:“C:\Temp\ConsoleApplication3\Debug\ConsoleApplication3.pdb” / DYNAMICBASE“ kernel32.lib”“ user32.lib”“ gdi32.lib”“ winspool.lib” “ comdlg32.lib”“ advapi32.lib”“ shell32.lib”“ ole32.lib”“ oleaut32.lib” “ uuid.lib”“ odbc32.lib”“ odbccp32.lib” / DEBUG / MACHINE:X86 /增加的 /PGD:“C:\Temp\ConsoleApplication3\Debug\ConsoleApplication3.pgd” / SUBSYSTEM:CONSOLE / MANIFESTUAC:“ level ='asInvoker'uiAccess ='false'” /ManifestFile:“Debug\ConsoleApplication3.exe.intermediate.manifest” / ERRORREPORT:PROMPT / NOLOGO / TLBID:1
Win32 DLL项目
/ OUT:“ C:\ Temp \ ConsoleApplication3 \ Debug \ Win32DLLProject1.dll” /清单/ NXCOMPAT /PDB:“C:\Temp\ConsoleApplication3\Debug\Win32DLLProject1.pdb” / DYNAMICBASE“ kernel32.lib”“ user32.lib”“ gdi32.lib”“ winspool.lib” “ comdlg32.lib”“ advapi32.lib”“ shell32.lib”“ ole32.lib”“ oleaut32.lib” “ uuid.lib”“ odbc32.lib”“ odbccp32.lib” /IMPLIB:“C:\Temp\ConsoleApplication3\Debug\Win32DLLProject1.lib” / DEBUG / DLL / MACHINE:X86 / INCREMENTAL /PGD:“C:\Temp\ConsoleApplication3\Debug\Win32DLLProject1.pgd” / SUBSYSTEM:WINDOWS / MANIFESTUAC:“ level ='asInvoker'uiAccess ='false'” /ManifestFile:"Debug\Win32DLLProject1.dll.intermediate.manifest“ / ERRORREPORT:PROMPT / NOLOGO / TLBID:1
Win32 Windows应用程序项目
/ OUT:“ C:\ Temp \ ConsoleApplication3 \ Debug \ Win32WindowsProject1.exe” /清单/ NXCOMPAT /PDB:“C:\Temp\ConsoleApplication3\Debug\Win32WindowsProject1.pdb” / DYNAMICBASE“ kernel32.lib”“ user32.lib”“ gdi32.lib”“ winspool.lib” “ comdlg32.lib”“ advapi32.lib”“ shell32.lib”“ ole32.lib”“ oleaut32.lib” “ uuid.lib”“ odbc32.lib”“ odbccp32.lib” / DEBUG / MACHINE:X86 /增加的 /PGD:“C:\Temp\ConsoleApplication3\Debug\Win32WindowsProject1.pgd” / SUBSYSTEM:WINDOWS / MANIFESTUAC:“ level ='asInvoker'uiAccess ='false'” /ManifestFile:“Debug\Win32WindowsProject1.exe.intermediate.manifest” / ERRORREPORT:PROMPT / NOLOGO / TLBID:1
因此我们可以看到,为/DLL
定义了/SUBSYSTEM:WINDOWS
。
然后我尝试用3个不同的SUBSYSTEM值构建一个DLL:
还有其他值,但是我只能使用上面的3来成功构建。其他值将导致链接错误,这意味着需要一些外部符号。
可能的SUBSYSTEM值的完整列表为:
您可以使用CFF资源管理器检查PE / COFF二进制文件。
SUBSYSTEM
标头字段位于PE / COFF文件的文件偏移0x14C
处。它是Optional Header
的一部分。
/ DLL / SUBSYESTEM:CONSOLE
/ DLL / SUBSYESTEM:WINDOWS
/ DLL和否/ SUBSYESTEM选项(通过在VS2015项目属性页中选择“不设置”
有趣的是,NOT SET
和WINDOWS
值导致二进制标头中的内容相同。
然后,我比较了3个DLL的整个二进制文件。似乎其余的二进制文件都是一样的,除了一些时间戳和调试信息。
这只是我发现的事实。 /SUBSYSTEM
选项如何影响二进制行为取决于加载程序如何解释此字段。
在我参与的一个项目中,/SUBSYSTEM:CONSOLE
和/DLL
一起使用,这与DLL项目的默认组合不同。但是似乎没有坏事发生。因此,我同意@FrédéricHamidi的观点,该标志对DLL没有功能影响。