我在这个案例的MSDN上找不到任何有用的东西。使用Dependency Walker,在模块列表中,我看到了控制台和图形用户界面的混合使用。
这对编译DLL有影响吗?
发布于 2012-07-30 14:37:00
此选项仅对应用程序(exe)有效,对库(dll)没有影响。
它的documentation说:
/SUBSYSTEM选项指定可执行文件的环境。
子系统的选择会影响链接器将选择的入口点符号(或入口点函数)。
这不会影响库,因为库有自己的(可选) entry point。
CyberShadow评论之后的附加信息:在加载DLL时,子系统字段本身似乎被忽略了。This article about CSRSS说(强调我的):
此外,每个进程都与一个特定的子系统结构相关联;此属性由链接器设置(在编译过程中),并驻留在以下PE结构字段中:...
发布于 2020-12-11 10:06:51
我下面的回答只是一些发现。
我尝试在VS2015中创建以下类型的项目:
下面是它们的完整链接选项:
Win32控制台应用程序项目
/OUT:"C:\Temp\ConsoleApplication3\Debug\ConsoleApplication3.exe“/PDB:"C:\Temp\ConsoleApplication3\Debug\ConsoleApplication3.pdb”
/MANIFEST /NXCOMPAT /DYNAMICBASE "kernel32.lib“"user32.lib”"gdi32.lib“"winspool.lib”"comdlg32.lib“"advapi32.lib”"shell32.lib“"ole32.lib”“ole32.lib”"oleaut32.lib“"uuid.lib”"odbc32.lib“"odbccp32.lib”/DEBUG /MACHINE:X86 /PGD:"C:\Temp\ConsoleApplication3\Debug\ConsoleApplication3.pgd“/SUBSYSTEM:CONSOLE uiAccess:”level=‘asInvoker’uiAccess='false'“/ManifestFile:"Debug\ConsoleApplication3.exe.intermediate.manifest”/NOLOGO /TLBID:1
Win32 DLL项目
/OUT:"C:\Temp\ConsoleApplication3\Debug\Win32DLLProject1.dll“/PDB:"C:\Temp\ConsoleApplication3\Debug\Win32DLLProject1.pdb”
/MANIFEST /NXCOMPAT /DYNAMICBASE "kernel32.lib“"user32.lib”"gdi32.lib“"winspool.lib”"comdlg32.lib“"advapi32.lib”"shell32.lib“"ole32.lib”“ole32.lib”"oleaut32.lib“"uuid.lib”"odbc32.lib“"odbccp32.lib”/IMPLIB:"C:\Temp\ConsoleApplication3\Debug\Win32DLLProject1.lib“/PGD:"C:\Temp\ConsoleApplication3\Debug\Win32DLLProject1.pgd”/SUBSYSTEM:WINDOWS /DLL /MACHINE:X86 /INCREMENTAL /MANIFESTUAC:“/ManifestFile:"Debug\Win32DLLProject1.dll.intermediate.manifest”=‘asInvoker’uiAccess='false'“/DEBUG /ERRORREPORT:PROMPT /NOLOGO /TLBID:1
Win32 Windows应用程序项目
/OUT:"C:\Temp\ConsoleApplication3\Debug\Win32WindowsProject1.exe“/PDB:"C:\Temp\ConsoleApplication3\Debug\Win32WindowsProject1.pdb”
/MANIFEST /NXCOMPAT /DYNAMICBASE "kernel32.lib“"user32.lib”"gdi32.lib“"winspool.lib”"comdlg32.lib“"advapi32.lib”"shell32.lib“"ole32.lib”“ole32.lib”"oleaut32.lib“"uuid.lib”"odbc32.lib“"odbccp32.lib”/DEBUG /MACHINE:X86 /PGD:"C:\Temp\ConsoleApplication3\Debug\Win32WindowsProject1.pgd“/SUBSYSTEM:WINDOWS uiAccess:”level=‘asInvoker’uiAccess='false'“/ManifestFile:"Debug\Win32WindowsProject1.exe.intermediate.manifest”/NOLOGO /TLBID:1
所以我们可以看到,对于一个/DLL,/SUBSYSTEM:WINDOWS是被定义的。
然后,我尝试用3个不同的子系统值构建一个DLL:
也有其他值,但我只能使用上面的3成功构建。其他值将导致链接错误,这意味着需要一些外部符号。
可能的子系统值的完整列表如下:

您可以使用CFF Explorer检查PE/COFF二进制文件。
COFF头字段位于PE/ SUBSYSTEM文件的文件偏移量0x14C。它是Optional Header的一部分。
/DLL /SUBSYESTEM:CONSOLE

/DLL /SUBSYESTEM:WINDOWS

/DLL和no /SUBSYESTEM选项(通过在VS2015项目属性页中选择NOT SET

有趣的是,NOT SET和WINDOWS值导致二进制头中的内容相同。
我比较了3个DLL的整个二进制文件。似乎其余的二进制文件都是一样的,除了一些时间戳和调试信息。
这只是我发现的一些事实。/SUBSYSTEM 选项如何影响二进制行为取决于加载器如何解释此字段。
在我参与的一个项目中,/SUBSYSTEM:CONSOLE和/DLL一起使用,这与DLL项目的默认组合不同。但似乎没有什么不好的事情发生。因此,我同意@Frédéric Hamidi的观点,即此标志对DLL没有任何功能影响。
https://stackoverflow.com/questions/11716350
复制相似问题