【发布时间】:2021-07-20 06:14:56
【问题描述】:
我正在尝试将针对 POSIX 编写的 Fortran-C 代码移植到 Windows。据我所知,大部分程序都可以在 Windows 上编译,只需要更改一些小命令。
在程序的fortran部分,有一行
call system("exec xmrcc >> output.log")
问题是,windows 没有任何exec 命令。但是,经过一番挖掘,我发现在 linux 上,exec 命令使用底层的execvp() 调用。在 Windows 上,MSVC++ 提供了_exec() 和相关函数系列。 _execlp() 或 _execlpe() 似乎是我想要的。
所以,我想用 C 函数替换 fortran 系统调用,该函数将环绕 execlpe() 并调用程序 xmrcc.exe。
但是,我无法弄清楚这些功能是如何工作的!我读过Microsoft documentation on exec、Use of execl (Arguments) 和C- Using exec() in windows。在遵循链接的最后一个问题的接受答案后,我编写了这段 C 代码来测试 _execlp()
#include <stdio.h>
#include <windows.h>
#include <process.h>
int main()
{
printf("started running");
_execlp("C::\\WINDOWS\\SYSTEM32\\CMD.EXE", "cmd.exe", "/c",
"echo", "foo",">G:\\Python\\foo.txt");
}
但是,在运行编译后的代码时,我只得到了“开始运行”的输出,然后它返回了; G:\Python 中没有 foo.txt 文件。然后我想可能是输出重定向引起了问题,所以我删除了它:
_execlp("C::\\WINDOWS\\SYSTEM32\\CMD.EXE", "cmd.exe", "/c", "echo", "foo");
还是什么都没有。它只打印“开始运行”,不打印“foo”。
我有两个主要问题:
-
如何在 Windows 上正确运行
_execlp()?(运行 xmrcc.exe 并将输出定向到日志) -
是否必须使用
_execlpe()来传递环境变量?(我不明白这是怎么回事。)
我正在使用 Microsoft Visual C++ v19 编译器。
[请不要提及 cygwin、mingw 或 WSL,它们不是我要找的。而且我知道不鼓励使用fortran中的系统调用,但程序不是我写的,我只是在移植它。
而且我需要使用_execlp(),因为它完全用子进程替换了调用进程,并且最接近linux的exec命令。这是必要的,因为程序的其他部分使用 PIDS,因此必须不产生具有不同 PID 的子进程。]
编辑:删除 exec shell 命令会起作用吗?如call system("xmrcc >> output.log) @ChrisDodd 在 cmets 中建议的。
【问题讨论】:
-
这里的
exec是内置的execshell,而不是exec系统调用(系统调用与系统库函数无关)。你可以通过删除它来做同样的事情——例如使用system("xmrcc >> output.log") -
使用
CreateProcess。 -
@IInspectable CreateProcess() 是否处理 PID?我需要 PID 保持不变。
-
@ChrisDodd 我知道 exec 是 shell 命令。如果我只是删除它,它不会创建一个新进程吗?我认为 exec 命令完全用子进程替换了调用进程,即当 xmrcc 结束时,shell 不会返回。
-
CreateProcess返回 - 其中包括 - 创建的进程的 PID。尽管 PID 在很大程度上是无用的,因为您无法知道任何给定值是否仍然指代同一进程。这不足为奇,因为在一个比 POSIX 试图捕获的(基本上是 60 年代的技术)先进得多的操作系统的上下文中,大多数 POSIX 的东西都相当无用。
标签: c windows visual-c++ porting