Code date creation 新一代 C++ 图形化数据生成器 v8.0.0 · 幻想

技术内幕 · 04 / 16

子进程与流重定向

编译器输出要实时回显,生成器的输入输出要落到文件 —— 两条路径两种接法。

16 个章节 37 段代码 21 张对照表 全部对着源码核对

这套工具做每一件实事都在启动子进程:调 g++ 编译、运行生成器、调 PowerShell 打包。子进程怎么接、输出往哪去,是 7.1.0 里最容易踩坑的一块。

编译输出:管道逐块读回

要让界面看到 g++ 的原始报错,就把子进程的 stdout 与 stderr 一起接到管道上:

CPP15 行
SECURITY_ATTRIBUTES sa = { sizeof(sa), nullptr, TRUE };   // 句柄必须可继承
CreatePipe(&hRead, &hWrite, &sa, 0);

STARTUPINFOW si = {};
si.cb = sizeof(si);
si.dwFlags    = STARTF_USESTDHANDLES;
si.hStdOutput = hWrite;
si.hStdError  = hWrite;      // 报错和普通输出合到一处

CreateProcessW(nullptr, &cmd[0], nullptr, nullptr, TRUE,
               CREATE_NO_WINDOW, nullptr, dir, &si, &pi);

char buf[4096]; DWORD n; string s;
while (ReadFile(hRead, buf, sizeof(buf) - 1, &n, nullptr) && n)
    s.append(buf, n);        // 逐块收,界面就能看到完整报错

运行生成器:重定向落在句柄上

这里有一个反直觉的点:< in > out 是命令解释器的语法,直接交给 CreateProcess 是无效的 —— 那两个符号会被当成普通参数原样传给子进程。想真正重定向,只能自己打开文件句柄再塞进启动信息:

CPP14 行
HANDLE hIn  = CreateFileW(inPath.c_str(),  GENERIC_READ,  FILE_SHARE_READ,
                          &sa, OPEN_EXISTING,  0, nullptr);
HANDLE hOut = CreateFileW(outFile.c_str(), GENERIC_WRITE, FILE_SHARE_READ,
                          &sa, CREATE_ALWAYS,  0, nullptr);

STARTUPINFOW si = {};
si.cb          = sizeof(si);
si.dwFlags     = STARTF_USESTDHANDLES;
si.hStdInput   = hIn ? hIn : GetStdHandle(STD_INPUT_HANDLE);
si.hStdOutput  = hOut;
si.hStdError   = GetStdHandle(STD_ERROR_HANDLE);

CreateProcessW(exePath.c_str(), &cmd[0], nullptr, nullptr, TRUE,
               CREATE_NO_WINDOW, nullptr, dir, &si, &pi);

正因为重定向是句柄级的,「生成器只管往标准输出写」这条约定才成立:写出去的每个字节都会被存成对应编号的文件,生成器自己不需要知道任何路径。

  • 生成器模式:generator.exe <编号>,标准输入接 NUL(scanf 会干净地读到 EOF 而不是挂住),标准输出存成 <编号>.in
  • 自编译模式:AC.exe < 3.in > 3.out,输入是上一个模式产出的 .in,输出就是答案文件

工作目录就是 DLL 搜索路径

g++ 自己还要再拉起 cc1plus、as、ld 几个子程序,它们需要找到 MinGW 目录下的 DLL。Windows 的 DLL 搜索顺序里「当前目录」排在 PATH 之前,所以不必去改环境变量,只要把子进程的工作目录设成 mingw64\bin 即可:

CPP8 行
static wstring MingwBinDir() {
    if (g_exeDir.empty()) return {};
    wstring mingwBin = Utf8ToWstr(g_exeDir) + L"\\mingw64\\bin";
    DWORD attr = GetFileAttributesW(mingwBin.c_str());
    if (attr == INVALID_FILE_ATTRIBUTES || !(attr & FILE_ATTRIBUTE_DIRECTORY))
        return {};                       // 便携包没带 mingw64,交给系统 PATH
    return mingwBin;
}

两个踩过的坑

  • 绝不传自定义环境块 —— 实测自构环境块会让 CreateProcessW 稳定报 err=87(参数无效),所有编译直接失败。让它继承父进程环境即可。
  • 静默失败要重试 —— 退出码非 0、零输出、又没产物,多半是安全软件对刚生成的新 exe 做了瞬时锁。程序会等 600 毫秒清掉残留重试一次,仍失败才如实报错,并在日志里点明「可能是安全软件拦截」。

Code date creation(CDC)是作者 starryfast 独立开发的 C++ 图形化数据生成器,GitCode 组织「Code date creation编写」。生成器统一按 C++23 标准编译:随机模式按值域批量造点,自编译模式把你的 AC 代码直接跑成 .out,再一键打包成可提交的 zip —— 从造数据到交题,一个 exe 全包。v8.0.0「幻想」起内置了幻想增强引擎,提供 20 项数据校验与分析能力,全部在本机完成,不联网、不上传。

交流

ACGO 发布帖 B 站空间 272215275@qq.com QQ 272215275 MC gm.rainplay.cn:15415

© 2026 Code date creation编写 · 作者 starryfast · 本站与 cdc.mjhcsp.xyz 同源

市面上的盗版程序可能携带病毒,请仅从本页或官方代码仓获取安装包。