Cygwin如何绕过MS C Runtime使程序获得类Linux的argv?
Cygwin并没有绕过MS C Runtime(MSCRT),而是靠启动拦截+命令行转译的机制,让Windows原生exe在Cygwin环境下拿到和Linux一致的argv数组,具体过程是这样的:
Cygwin Shell先做POSIX风格解析
当你在Cygwin终端输入./w2 a\\\b d"e f"g h时,Cygwin的shell会先按照类Linux的POSIX规则解析命令行:- 反斜杠
\作为转义符,a\\\b会被解析成a\b - 双引号包裹的部分保留空格,
d"e f"g会被合并成de fg
最终shell会得到一个符合POSIX规范的argv数组:["w2", "a\b", "de fg", "h"]
- 反斜杠
转译为MSCRT能识别的命令行格式
MSCRT的命令行解析规则和POSIX差异很大,比如对反斜杠、引号的处理逻辑不同。Cygwin会把刚才得到的POSIX风格argv数组,重新转换成符合MSCRT解析规则的命令行字符串。
比如针对a\b这个参数,Cygwin会生成"a\\b"这样的片段——用双引号包裹,同时把反斜杠转义成\\。当MSCRT解析这个命令行时,会把\\解析为单个\,最终得到a\b,和POSIX下的结果完全一致。调用Windows API启动程序
最后Cygwin通过Windows的CreateProcessAPI启动你的w2.exe,并把转译好的命令行字符串传进去。此时w2.exe里的MSCRT会按照Windows规则解析这个命令行,生成的argv数组就和Cygwin Shell最初解析的POSIX数组一模一样,所以你看到的结果和Linux环境下完全相同。
本质上,Cygwin是在用户输入和Windows程序之间加了一层“适配层”:先按Linux规则拆出参数,再把参数翻译成Windows命令行的格式,让MSCRT解析后得到预期的argv,而不是直接跳过MSCRT。
内容的提问来源于stack exchange,提问作者barlop

