【问题标题】:Write and read boost into POSIX pipe (No boost.iostream)将 boost 写入和读取到 POSIX 管道(无 boost.iostream)
【发布时间】:2021-03-09 17:18:05
【问题描述】:

我有一个使用 boost 的序列化将对象归档到文件的设置。我想要/需要做同样的事情,但写入 POSIX 管道而不是基本文件。

一个简单的数据包:

#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/export.hpp>
#include "AbstractPacket.hpp"

struct SimplePacket final: public AbstractPacket{
    bool value;

    BooleanPacket() noexcept = default;

    template <typename Archive>
    void serialize(Archive& a, const unsigned int) {
        a& boost::serialization::base_object<AbstractPacket>(*this);
        a& value;
    }

    ~SimplePacket() = default;
};

编写简单的数据包:

#include "SimplePacket.hpp"
BOOST_CLASS_EXPORT_GUID(SimplePacket, "SimplePacket")
//...//
void write(Packet* packet){
    std::ofstream file;
    file.open(_client_pipe, std::fstream::out | std::fstream::binary);
    if (file.is_open()) {
        boost::archive::binary_oarchive oa(file);
        oa << packet;
        file.close();
    }
}

这会将数据包(增强序列化存档)写入文件。但是,我需要写入 posix 管道。 我有read,使用 boost.iostream 可以从文件描述符打开到 POSIX 管道的文件流。 我还没有找到一个明确的方法来做到这一点; 但是我想这样做不使用 boost.iostream,这是否可能,如果可以,我该怎么做?

【问题讨论】:

  • 您如此坚决地断言您不能使用 boost iostream 的原因是什么?您对此的回答可能会使我要输入的每个答案无效。不要只是/声称/事情。说明您的动机,以便我们提供帮助
  • @sehe 主要是想看看有没有cpp原生的解决方案;我承认这可能意味着我会使很多答案无效;对困惑感到抱歉 ! (谢谢!)
  • FWIW Boost Iostream 对流描述符的支持与 Asio 一样“原生”(Process 在后台使用它,只是以独立于平台的方式添加管道创建)。我想我什至记得它是库的仅标题子集的一部分。
  • misremembered that,但是 - 无论如何你都在使用 Boost 序列化......所以你也可以。除此之外,显然还有 C 代码,所以你总是可以“自己写”

标签: c++ boost posix named-pipes


【解决方案1】:

Boost Asio + Process 一起也可以做到这一点:

使用 Boost 过程

Live On wandbox

size_t write(Packet* packet) {
    boost::asio::streambuf sb;
    {
        std::ostream                    os(&sb);
        boost::archive::binary_oarchive oa(os);
        oa << packet;
    }

    boost::asio::io_context ctx;
    boost::process::async_pipe p(ctx); // opens a pipe (pair of fds)

    size_t bytes = write(p, sb);       // throws system_error on error

    return bytes;
}

如果您已经拥有管道,请使用async_pipe 的适当构造函数来传递 fds。

仅使用 Boost Asio

另外,如果您已经拥有管道 fd,我建议您根本不要使用 Boost Process:

boost::asio::io_context               ctx;
boost::asio::posix::stream_descriptor s(ctx, 2); // STDERR

size_t bytes = write(s, sb); // throws system_error on error
s.release();                 // to avoid close on destruction

请特别注意release(),它可能会节省您摸不着头脑的时间。

Live On Wandbox

#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/export.hpp>

struct AbstractPacket {
    virtual ~AbstractPacket() = default;
    template <typename Archive> void serialize(Archive&, unsigned) {}
};

BOOST_SERIALIZATION_ASSUME_ABSTRACT(AbstractPacket)

struct BooleanPacket : public AbstractPacket {
    bool value;

    template <typename Archive> void serialize(Archive& a, unsigned) {
        a& boost::serialization::base_object<AbstractPacket>(*this);
        a& value;
    }
};

BOOST_CLASS_EXPORT(BooleanPacket)

#include <boost/asio.hpp>

size_t write(AbstractPacket* packet) {
    boost::asio::streambuf sb;
    {
        std::ostream                    os(&sb);
        boost::archive::text_oarchive oa(os);
        oa << packet;
    }

    boost::asio::io_context               ctx;
    boost::asio::posix::stream_descriptor s(ctx, 2); // STDERR

    size_t bytes = write(s, sb); // throws system_error on error
    s.release();                 // to avoid close on destruction

    return bytes;
}

#include <iostream>
int main() {
    auto test   = new BooleanPacket(); // please use smart pointers
    test->value = true;

    std::cout << "Bytes written: " << write(test) << "\n";

    delete test; // please use smart pointers
}

打印标准错误:

22 serialization::archive 18 1 13 BooleanPacket 1 0
0 1 0
1 1

标准输出:

Bytes written: 62

【讨论】:

  • Boost 太棒了
猜你喜欢
  • 2016-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多