2

创建一个进程并等待它完成后,它的 STARTUPINFO 是否仍然可用或已被破坏?

STARTUPINFO si;

bRes = CreateProcess(NULL, command, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);

dwRes = WaitForSingleObject(pi.hProcess, INFINITE);

在此之后是否si被修改/销毁或保持不变?

4

3 回答 3

2

Windows 为新进程创建启动信息结构的副本。这必须发生,因为新进程具有全新的地址空间并且看不到您的结构。

现在,你的结构会发生什么?好吧,文档有答案。参数注释如下:

_In_ LPSTARTUPINFO lpStartupInfo

_In_意味着结构的内容不会被调用修改CreateProcess。因此,您可以确信在CreateProcess返回时,启动信息结构没有被修改。

于 2013-03-21T10:02:57.840 回答
0

Windows 创建的 STARTUPINFO的副本被销毁。但是您提供给 CreateProcess 函数的结构仍然存在。

于 2013-03-21T09:46:38.937 回答
0

如果你像以前那样声明它

STARTUPINFO si;

然后,当声明它的程序部分完成时,它被 C 销毁(称为“超出范围”)。例如:

void myfunct() {
  STARTUPINFO si1;
  if (condition) {
    STARTUPINFO si2;
    //...
  } //si2 destroyed here
  //...
} //si1 destroyed here

即使CreateProcess()函数想要保留 si1 或 si2,它也不能。因为无论你做什么,它们都会在那个时候被摧毁。

现在,如果您像这样创建 si:

STARTUPINFO *si = malloc(sizeof(STARTUPINFO));

那么它只会在你明确调用时被销毁

free(si);

一些 API 函数需要你给他们一些他们可以保留的东西。对于这些函数,您必须在一秒钟或更复杂的方式中分配参数,并且它们会在文档中告诉您何时必须在稍后销毁它。

但是大多数 API 函数只是复制您传递给它们的任何内容并保留源代码,因此可以将指针传递给以第一种方式声明的结构。

请注意,通常“将某些内容传递给 API 并依赖 API 销毁它”是不合适的。您调用的应用程序和 API 函数很可能使用不同的内存管理器。在一个中分配的东西不能在另一个中释放。

因此,大多数情况下,此类 API 会希望您通过调用某些特定函数来分配数据,或者(更常见)稍后自己删除数据。

MYPARAM *p = malloc(sizeof(MYPARAM));
APIOpen(p);
//...much later
APIClose(p);
//It's now safe to free p
free(p);
于 2013-03-21T10:08:22.013 回答