【问题标题】:Sending Data Structures over Named Pipes通过命名管道发送数据结构
【发布时间】:2015-05-10 02:34:38
【问题描述】:

我发现了这个 StackOverflow 问题:

Create Named Pipe C++ Windows

并创建了这个类:

#pragma once

#define PIPE_FD TEXT("\\\\.\\pipe\\somepipe")

#define BUFFER_SIZE 1024

// CPipe Class
class CPipe
{

private:

    //
    // Variables
    //

    HANDLE hPipe;
    char buffer[BUFFER_SIZE];
    DWORD dwRead;
    DWORD dwWritten;

public:

    bool CreatePipe()
    {
        hPipe = CreateNamedPipe(PIPE_FD, PIPE_ACCESS_DUPLEX | PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, PIPE_WAIT, 1, BUFFER_SIZE * 16, BUFFER_SIZE * 16, NMPWAIT_USE_DEFAULT_WAIT, NULL);

        return (hPipe == NULL) ? false : true;
    }

    bool CreatePipeFile()
    {
        hPipe = CreateFile(PIPE_FD, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

        return (hPipe == NULL) ? false : true;
    }

    void Destroy()
    {
        DisconnectNamedPipe(hPipe);
    }

    bool IsPipe()
    {
        return (hPipe == NULL) ? false : true;
    }

    bool IsConnected()
    {
        return (ConnectNamedPipe(hPipe, NULL) != FALSE) ? true : false;
    }

    void Read()
    {
        while (ReadFile(hPipe, buffer, sizeof(buffer), &dwRead, NULL) != FALSE)
        {
            /* do something with data in buffer */
            printf("%s", buffer);
        }
    }

    void Write()
    {
        WriteFile(hPipe, "Hello Pipe\n", 12, &dwWritten, NULL);

        CloseHandle(hPipe);
    }
};

extern CPipe gPipe;

主进程:

    gPipe.CreatePipe();
    while (gPipe.IsPipe())
    {
        if (gPipe.IsConnected())
        {
            gPipe.Read();
        }

        gPipe.Destroy();
    }

远程:

    gPipe.CreatePipeFile();
    if (gPipe.IsPipe())
    {
        gPipe.Write();
    }

效果很好。我可以在两个应用程序之间发送“Hello Pipe\n”。但是,我正在尝试修改它以发送数据结构而不是字符串。

例如这个结构:

struct Test_t
{
    int x;
    int y;
    float J[3];
    bool Yes;
};

这样,客户端可以通过管道发送结构,服务器可以从管道读取结构并相应地更新本地服务器结构。

我试过了:

reinterpret_cast<char*>(&test);

但我无法让它工作。有什么想法吗?

感谢任何帮助。

【问题讨论】:

  • 提醒您,如果您将该结构更改为非 POD,则仅传递整个结构的方法将不起作用。

标签: c++ ipc named-pipes


【解决方案1】:

重新解释的演员表应该如下所示:

reinterpret_cast<void*>(&test);

您还需要确保获得正确传输的数据量(sizeof 是您的朋友)。

请注意,发送这样的结构可能会有风险。

  • 发送的对象必须是普通的旧数据对象,否则它们将无法正确序列化。有关普通旧数据的更多信息,请参阅What are POD types in C++?。指针成员、虚函数等将不起作用。
  • 如果相互交谈的两个进程对结构包装有不同的想法,那么对方就会出错。只要您可以完全控制构建环境,这应该没问题,但是当事情开始出现问题时,您可以修复一些非常讨厌的错误。

除非您有极端的性能考虑,否则您应该研究一些更有条理的方法来序列化您通过管道发送的数据,例如 google 协议缓冲区或 boost::serialize,这将确保有线格式不那么脆弱。协议缓冲区(和许多其他技术)的优势在于不是特定于 c++ 的,因此您可以在使用不同编程语言创建的进程之间进行对话。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多