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

CS.*_*CS. 12 dll winapi visual-studio visual-c++

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

这在编译DLL时是否会产生影响?

Fré*_*idi 13

此选项仅对applications(exe)有影响,而不对libraries(dll)有影响.

它的文件说:

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

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

这不会影响具有自己的(可选)入口点的库.

Cyber​​Shadow评论后的其他信息:加载DLL时,子系统字段本身似乎被忽略.这篇关于CSRSS的文章说(强调我的):

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

  • Frédéric,您的回答似乎是基于对问题的不完整理解,而且您似乎也不理解 mox 的评论。每个 PE 文件(EXE、DLL、SYS...)都有一个头字段(特别是 IMAGE_OPTIONAL_HEADER.Subsystem),它显然可以接受十多个有意义的不同值(请参阅 IMAGE_SUBSYSTEM_* 枚举)。`/SUBSYSTEM` 链接器选项不仅仅选择一个入口点,它还填充标题中的 `Subsystem` 字段。问题是:加载 DLL 时,DLL 本身中的“子系统”字段*是否有任何影响? (2认同)

smw*_*dia 5

我的以下回复只是一些发现。

\n

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

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

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

\n

Win32 控制台应用程序项目

\n
\n

/OUT:"C:\\Temp\\ConsoleApplication3\\Debug\\ConsoleApplication3.exe"\n/MANIFEST /NXCOMPAT\n/PDB:"C:\\Temp\\ConsoleApplication3\\Debug\\ConsoleApplication3.pdb" \n/DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib"\n"comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib "\n"uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG /MACHINE:X86\n/INCRMENTAL\n/PGD:"C:\\Temp\\ConsoleApplication3\\Debug\\ConsoleApplication3.pgd "\n /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level=\'asInvoker\' uiAccess=\'false\'"\n/ManifestFile:"Debug\\ConsoleApplication3.exe.intermediate.manifest"\n/ERRORREPORT:PROMPT /无标志/TLBID:1

\n
\n

Win32 DLL 项目

\n
\n

/OUT:"C:\\Temp\\ConsoleApplication3\\Debug\\Win32DLLProject1.dll"\n/MANIFEST /NXCOMPAT\n/PDB:"C:\\Temp\\ConsoleApplication3\\Debug\\Win32DLLProject1.pdb" \n/DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib"\n"comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib "\n"uuid.lib" "odbc32.lib" "odbccp32.lib"\n/IMPLIB:"C:\\Temp\\ConsoleApplication3\\Debug\\Win32DLLProject1.lib"\n/DEBUG /DLL /MACHINE: X86 /INCRMENTAL\n/PGD:"C:\\Temp\\ConsoleApplication3\\Debug\\Win32DLLProject1.pgd"\n /SUBSYSTEM:WINDOWS /MANIFESTUAC:"level=\'asInvoker\' uiAccess=\'false\' "\n/ManifestFile:"Debug\\Win32DLLProject1.dll.intermediate.manifest"\n/ERRORREPORT:PROMPT /NOLOGO /TLBID:1

\n
\n

Win32 Windows 应用程序项目

\n
\n

/OUT:"C:\\Temp\\ConsoleApplication3\\Debug\\Win32WindowsProject1.exe"\n/MANIFEST /NXCOMPAT\n/PDB:"C:\\Temp\\ConsoleApplication3\\Debug\\Win32WindowsProject1.pdb" \n/DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib"\n"comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib "\n"uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG /MACHINE:X86\n/INCRMENTAL\n/PGD:"C:\\Temp\\ConsoleApplication3\\Debug\\Win32WindowsProject1.pgd "\n /SUBSYSTEM:WINDOWS /MANIFESTUAC:"level=\'asInvoker\' uiAccess=\'false\'"\n/ManifestFile:"Debug\\Win32WindowsProject1.exe.intermediate.manifest"\n/ERRORREPORT:PROMPT /无标志/TLBID:1

\n
\n

所以我们可以看到,对于 a /DLL,/SUBSYSTEM:WINDOWS是有定义的。

\n

然后我尝试构建一个具有 3 个不同 SUBSYSTEM 值的 DLL:

\n
    \n
  • 安慰
  • \n
  • 视窗
  • \n
  • 没有设置
  • \n
\n

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

\n

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

\n

在此输入图像描述

\n

您可以使用 CFF Explorer 检查 PE/COFF 二进制文件。

\n

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

\n

/DLL /子系统:控制台

\n

在此输入图像描述

\n

/DLL /子系统:WINDOWS

\n

在此输入图像描述

\n

/DLL 且没有 /SUBSYESTEM 选项(通过在 VS2015 项目属性页中选择 NOT SET

\n

在此输入图像描述

\n

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

\n

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

\n

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

\n

在我参与的一个项目中,/SUBSYSTEM:CONSOLE/DLL一起使用,这与 DLL 项目的默认组合不同。但似乎没有什么不好的事情发生。所以我同意 @Fr\xc3\xa9d\xc3\xa9ric Hamidi 的观点,即该标志对 DLL 没有功能影响。

\n