【问题标题】:do writefile function twice执行两次 writefile 函数
【发布时间】:2026-02-06 07:00:02
【问题描述】:
bool sendMessageToGraphics(char* msg)
    {
        //char ea[] = "SSS";
        char* chRequest = msg;  // Client -> Server
        DWORD cbBytesWritten, cbRequestBytes;

        // Send one message to the pipe.

        cbRequestBytes = sizeof(TCHAR) * (lstrlen(chRequest) + 1);

        if (*msg - '8' == 0)
        {
            char new_msg[1024] = { 0 };
            string answer = "0" + '\0';
            copy(answer.begin(), answer.end(), new_msg);
            char *request = new_msg;
            WriteFile(hPipe, request, cbRequestBytes, &cbRequestBytes, NULL);

        }

        BOOL bResult = WriteFile(           // Write to the pipe.
            hPipe,                      // Handle of the pipe
            chRequest,                  // Message to be written
            cbRequestBytes,             // Number of bytes to writ
            &cbBytesWritten,            // Number of bytes written
            NULL);                      // Not overlapped 

        if (!bResult/*Failed*/ || cbRequestBytes != cbBytesWritten/*Failed*/)
        {
            _tprintf(_T("WriteFile failed w/err 0x%08lx\n"), GetLastError());
            return false;
        }

        _tprintf(_T("Sends %ld bytes; Message: \"%s\"\n"),
            cbBytesWritten, chRequest);

        return true;

    }

在运行第一个 writefile 之后(如果是 '8'),另一个 writefile 函数不能正常工作,有人能理解为什么吗? 函数 sendMessageToGraphics 需要发送移动到棋盘

【问题讨论】:

  • 如何它“工作正常”?当您第二次调用该函数时会发生什么?你怎么称呼你的sendMessageToGraphics 函数?为什么不检查第一次WriteFile 调用的结果?
  • 第二次没有到达终点(_tprintf 部分)它只是返回到调用 sendMessageToGraphics 的函数
  • 哦,而不是做例如*msg - '8' == 0 如果你这样做了,会不会更容易(而且更“可读”) msg[0] == '8'?
  • 可能是,但我想这不是问题
  • 所以你的意思是函数只是返回,甚至没有打印错误信息?您是否尝试过在调试器中单步执行该函数?

标签: c++ windows chess writefile


【解决方案1】:

你的代码有两个问题:

首先,有一个(小)问题,您在条件语句中初始化一个字符串。你这样初始化它:

string answer = "0" + '\0';

这并不像你认为的那样。它将使用const char*char 作为其参数类型来调用operator+。这将执行指针添加,将 '\0' 的值添加到存储常量的位置。由于'\0' 将被转换为0 的整数值,它不会向常量添加任何内容。但是您的字符串最终没有'\0' 终止符。您可以通过将语句更改为:

string answer = std::string("0") + '\0';

但真正的问题在于您使用大小变量的方式。您首先将 size 变量初始化为输入变量的字符串长度(包括终止 '\0' 字符)。然后在条件语句中创建一个传递给WriteFile 的新字符串,但仍使用原始大小。这可能会导致缓冲区溢出,这是未定义的行为。您还将大小变量设置为写入文件的字节数。然后稍后您在下一次调用中再次使用相同的值。你从来没有真正检查过这个值,所以这可能会导致问题。

更改此设置的最简单方法是确保您的尺寸设置正确。例如,您可以这样做,而不是第一次调用:

WriteFile(hPipe, request, answer.size(), &cbBytesWritten, NULL);

然后在下次调用WriteFile之前检查返回值WriteFilecbBytesWritten的值,这样你就知道你的第一次调用也成功了。

另外,不要忘记在大小计算中删除您的sizeof(TCHAR) 部分。您永远不会在代码中使用TCHAR。您的输入是常规的char*,您在条件中使用的字符串也是如此。我还建议将 WriteFile 替换为 WriteFileA 以表明您正在使用此类字符。

最后,确保您的服务器实际上正在从您写入的句柄中读取字节。如果您的服务器没有从句柄读取,WriteFile 函数将冻结,直到它可以再次写入句柄。

【讨论】: