将 boost 写入和读取到 POSIX 管道(否 boost.iostream)
Write and read boost into POSIX pipe (No boost.iostream)
我有一个使用 boost 序列化将对象存档到文件的设置。我 want/need 做同样的事情,但写入 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 管道。
我有 使用 boost.iostream 是否可以从其文件描述符将文件流打开到 POSIX 管道。
我还没有找到一个明确的方法来做到这一点; 但是我想在不使用boost.iostream的情况下这样做,这可能吗?如果可以,我该怎么做?
结合使用 Boost Asio + Process 也可以做到这一点:
使用升压过程
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()
这可能会节省您挠头的时间。
#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 序列化将对象存档到文件的设置。我 want/need 做同样的事情,但写入 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 管道。
我有
结合使用 Boost Asio + Process 也可以做到这一点:
使用升压过程
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()
这可能会节省您挠头的时间。
#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