对于这种情况,我在 MSDN 上找不到任何有用的东西。使用 Dependency Walker ,在模块列表中,我看到了控制台和 GUI 的混合使用。
这对编译 DLL 有影响吗?
最佳答案
我下面的回复只是一些发现。
我尝试在 VS2015 中创建以下类型的项目:
以下是他们的完整链接选项:
Win32 控制台应用程序项目
/OUT:"C:\Temp\ConsoleApplication3\Debug\ConsoleApplication3.exe" /MANIFEST /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 /INCREMENTAL /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" /MANIFEST /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" /MANIFEST /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 /INCREMENTAL /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 Explorer 检查 PE/COFF 二进制文件。
SUBSYSTEM
头域位于文件偏移0x14C
PE/COFF 文件。它是 Optional Header
的一部分./DLL/SUBSYESTEM:控制台
/DLL/SUBSYESTEM:WINDOWS
/DLL 并且没有/SUBSYESTEM 选项(通过在 VS2015 项目属性页面中选择 NOT SET
有趣的是,
NOT SET
和 WINDOWS
值导致二进制 header 中的相同内容。我比较了 3 个 DLL 的整个二进制文件。除了一些时间戳和调试信息外,其余的二进制文件似乎都是一样的。
这只是我发现的一些事实。如何
/SUBSYSTEM
选项影响二进制行为取决于加载器如何解释该字段。 在我参与的其中一个项目中,
/SUBSYSTEM:CONSOLE
和 /DLL
一起使用,这与 DLL 项目的默认组合不同。但似乎没有什么不好的事情发生。所以我同意@Frédéric Hamidi 的观点,即这个标志对 DLL 没有功能影响。
关于visual-studio -/SUBSYSTEM :CONSOLE to/SUBSYSTEM:WINDOWS in a DLL 之间切换的影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11716350/