在/ SUBSYSTEM:CONSOLE到/ SUBSYSTEM:WINDOWS在DLL中切换的影响

时间:2012-07-30 06:29:06

标签: visual-studio winapi visual-c++ dll

在这种情况下,我在MSDN上找不到任何有用的东西。使用Dependency Walker,在模块列表中,我看到了Console和GUI的混合使用。

编译DLL时会产生影响吗?

2 个答案:

答案 0 :(得分:12)

此选项仅对应用程序(exe)产生影响,而不对库(dll)产生影响。

documentation说:

  

/SUBSYSTEM选项指定可执行文件的环境。

     

子系统的选择会影响入口点符号(或入口点)   函数)链接器将选择。

这不会影响具有自己的(可选)entry point

的库

Cyber​​Shadow评论后的其他信息:加载DLL时,子系统字段本身似乎被忽略。 This article about CSRSS说(强调我的):

  

此外,每个进程都与一个特定子系统相关联;   此属性由链接器设置(在编译期间   过程),并驻留在以下PE结构字段中:[...]

答案 1 :(得分:2)

我下面的答复只是一些发现。

我试图在VS2015中创建以下类型的项目:

  • Win32控制台应用程序项目
  • Win32 DLL项目
  • Win32 Windows应用程序项目

以下是其完整的链接选项:

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:

  • 控制台
  • WINDOWS
  • 未设置

还有其他值,但是我只能使用上面的3来成功构建。其他值将导致链接错误,这意味着需要一些外部符号。

可能的SUBSYSTEM值的完整列表为:

enter image description here

您可以使用CFF资源管理器检查PE / COFF二进制文件。

SUBSYSTEM标头字段位于PE / COFF文件的文件偏移0x14C处。它是Optional Header的一部分。

/ DLL / SUBSYESTEM:CONSOLE

enter image description here

/ DLL / SUBSYESTEM:WINDOWS

enter image description here

/ DLL和否/ SUBSYESTEM选项(通过在VS2015项目属性页中选择“不设置”

enter image description here

有趣的是,NOT SETWINDOWS值导致二进制标头中的内容相同。

然后,我比较了3个DLL的整个二进制文件。似乎其余的二进制文件都是一样的,除了一些时间戳和调试信息。

这只是我发现的事实。 /SUBSYSTEM选项如何影响二进制行为取决于加载程序如何解释此字段。

在我参与的一个项目中,/SUBSYSTEM:CONSOLE/DLL一起使用,这与DLL项目的默认组合不同。但是似乎没有坏事发生。因此,我同意@FrédéricHamidi的观点,该标志对DLL没有功能影响。