Win32 C API:替代损坏的execl*()系列函数?
Win32 C API: Alternative to broken execl*() family of functions?
所以,在Windows上,execl()似乎在不同的Windows版本中以不同的方式被破坏。我花了很多时间来缩小范围和调试,这并没有真正的意义,我只能认为Microsoft的execl()(实际上是execlp()对我来说)的实现有问题。
唯一的Windows版本execlp()似乎在7上正常工作。
在Windows 10上,它工作正常,直到我在MinGW中使用-mwindows进行编译。 然后它只是让我的程序以零退出代码终止。
在 Windows XP 上,它将参数参数中的空格解释为单独的参数,尽管函数原型的性质明确指定了参数的实际数量......
所以,看起来我将不得不使用一些Windows本机函数并将其包装在"#ifdef WIN32"中。
我真正需要的是 execl()(execlp 不是必需的)类似于 Windows 上的行为,因为它用新的进程映像替换当前进程映像,并像 execl() 一样保持网络描述符打开。
我真的不知道什么是好的选择,虽然 CreateProcess 似乎在某种程度上能够做到这一点,但我找不到足够的信息来说明我正在尝试做什么。
任何帮助,不胜感激。谢谢!
不幸的是,您将需要在Windows上使用完全不同的代码路径,因为在win32
子系统中,创建进程与在单个调用中加载和运行新映像耦合在一起:CreateProcess()
。
在典型的 posix 场景中,您将fork()
新进程,设置诸如文件描述符之类的内容,然后exec*()
新的二进制文件。要在 Windows 中实现类似的东西,您必须依靠从中获得的可能性CreateProcess()
.对于打开的文件(或套接字),win32
使用"句柄",这些句柄可以标记为可继承,例如,我对管道执行以下操作:
HANDLE pin, pout;
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = 0;
sa.bInheritHandle = 1;
if (!CreatePipe(&pin, &pout, &sa, 0))
{
fprintf(stderr, "Error creating pipe: %lun", GetLastError());
return;
}
这样,管道的句柄是可继承的。然后,当调用CreateProcess()
时,通过传递1
(或TRUE
)bInheritHandles
,新进程继承所有以这种方式标记的句柄。在此示例中,我执行以下操作:
STARTUPINFO si;
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
si.hStdInput = nul;
si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
si.dwFlags |= STARTF_USESTDHANDLES;
// simple example, my production code looks different, e.g. quoting the command:
char cmdline[1024];
strcpy(cmdline, exename);
strcat(cmdline, " ");
snprintf(cmdline + strlen(cmdline), 1024 - strlen(cmdline), "%" PRIxPTR, (uintptr_t)pout);
// [...]
PROCESS_INFORMATION pi;
CreateProcess(0, cmdline, 0, 0, 1, 0, 0, 0, &si, &pi);
在孩子身上,管道可以这样使用:
uintptr_t testPipeHandleValue;
if (sscanf(argv[1], "%" SCNxPTR, &testPipeHandleValue) != 1)
{
exit(EXIT_FAILURE);
}
int testPipeFd = _open_osfhandle(
(intptr_t)testPipeHandleValue, _O_APPEND | _O_WRONLY);
FILE *testPipe = _fdopen(testPipeFd, "a");
setvbuf(testPipe, 0, _IONBF, 0);
当然,对于网络套接字来说,这看起来会有所不同,但我希望总体思路有所帮助。
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么使用 "this" 指针调用派生成员函数?
- 将对象数组的引用传递给函数
- 函数调用中参数的顺序重要吗
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用不带参数的函数访问结构元素
- 从 c 或 cpp 系列子函数返回到主函数
- Win32 C API:替代损坏的execl*()系列函数?
- 构造函数系列
- 在参数中传递给 exec*() 函数系列的内存会发生什么情况
- 系列.println改变函数返回值(Arduino)