与 boost::asio 一起使用的 std::string 的替代品

发布于 2024-10-21 05:05:34 字数 1355 浏览 3 评论 0原文

boost::asio 的各种readwrite 函数和方法接受boost::asio::buffer。根据缓冲区的文档,可变的 std::string 不能包装在 boost::asio::buffer 中,因此不能用于 asio 的 read 函数。这可能是由于 std::string 不允许对其内部缓冲区进行可变访问(之前已讨论过此处)。

这很遗憾,因为 std::string 是在 C++ 中表示可变数据缓冲区的便捷方法。如果没有它,我们要么只剩下 POD 数组、boost::arraystd::vector。前两个对于可变长度消息来说不方便。 std::vector 可以工作,但这是一种不自然的方式来携带数据缓冲区 (*)

问题:

  1. 是否有其他替代 std::string 的方法boost::asio 用于读取缓冲区?我在这里错过了什么吗?
  2. 我想知道为什么可变缓冲区支持 std::vector 。是因为它保证其内部缓冲区在内存中是连续的,并允许使用 &vec[0] 对其进行可变访问?

提前致谢


(*)恕我直言。例如,看看 protobuf 序列化 - 它提供序列化为 std::string,但不提供序列化为 std::vector,至少不是明确地。


编辑:毕竟我最终使用了vectorprotobuf 允许通过采用指针 (&vec[0]) 的 SerializeToArray 调用序列化为 vector 可以传递到那里)。

boost::asio's various read and write functions and methods accept boost::asio::buffer. According to buffer's documentation, a mutable std::string cannot be wrapped in boost::asio::buffer, and thus cannot be used for asio's read functions. This is probably due to the fact that std::string does not allow mutable access to its internal buffer (this was discussed previously here).

This is a shame, because std::string is a convenient way to represent mutable buffers of data in C++. Without it, we're either left with POD arrays, boost::array and std::vector<char>. The first two are inconvenient with variable-length messages. std::vector<char> can work, but it's an unnatural way to carry buffers of data around (*)

Questions:

  1. Are there other alternatives to std::string with boost::asio for reading buffers? Am I missing something here?
  2. I wonder why std::vector<char> is supported in a mutable buffer. Is it because it guarantees its internal buffer is contiguous in memory and allows mutable access to it with &vec[0] ?

Thanks in advance


(*) IMHO. Look at protobuf serialization for instance - it offers serialization into std::string but not into std::vector<char>, at least not explicitly.


EDIT: I ended up using vector<char> after all. protobuf allows serialization into a vector<char> by means of the SerializeToArray call which takes a pointer (&vec[0] can be passed there).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

如歌彻婉言 2024-10-28 05:05:34

使用 &str[0] 对字符串缓冲区的可变访问在所有已知实现上都可以正常工作,并且即将推出的 C++0x 标准化的措辞使其得到正式允许。

尽管如此,我认为您认为 std::vector 是可变长度缓冲区的不自然表示是疯狂的。

Mutable access to a string buffer using &str[0] works fine on all known implementations, and the wording of the upcoming C++0x standardizes makes it officially allowed.

Still, I think you're insane to think that a std::vector is an unnatural representation for a variable-length buffer.

成熟稳重的好男人 2024-10-28 05:05:34

这是为了回答 Eli 的评论

我没有在我的文章中提到 asio::streambuf
最初提出问题,确实是因为
我不是 100% 清楚如何使用它
具有固定大小的读取和 asio。可以
你指出一个例子(或者添加一个例子
一个答案)展示如何阅读
固定长度的块变成
std::sstream

这是关于使用 asio 的之前的答案 ::streambufBoost.Serialization。 asio 文档也有一个同步读取的示例:

boost::asio::streambuf b;

// reserve 512 bytes in output sequence
boost::asio::streambuf::mutable_buffers_type bufs = b.prepare(512);

size_t n = sock.receive(bufs);

// received data is "committed" from output sequence to input sequence
b.commit(n);

std::istream is(&b);
std::string s;
is >> s;

This is to answer Eli's comment

I didn't mention asio::streambuf in my
question originally, indeed because it
wasn't 100% clear to me how to use it
with fixed size reads and asio. Could
you point to an example (or add one as
an answer) of showing how to read
fixed-length chunks into a
std::sstream?

Here's a previous answer about using asio::streambuf and Boost.Serialization. The asio documentation also has an example of a synchronous read:

boost::asio::streambuf b;

// reserve 512 bytes in output sequence
boost::asio::streambuf::mutable_buffers_type bufs = b.prepare(512);

size_t n = sock.receive(bufs);

// received data is "committed" from output sequence to input sequence
b.commit(n);

std::istream is(&b);
std::string s;
is >> s;
醉酒的小男人 2024-10-28 05:05:34

1) 可以通过检查 asio 找到替代方案::buffer() 函数,返回 mutable_buffers_1 的重载。更灵活(但可能不是最佳)的选项是 asio::streambuf,对于 (async_)read_until 很有用。

如果您有固定大小的字段协议,您可以使用 asio::mutable_buffer 数组。例如

using boost::asio;
int i;
short s;
char data[data_size]; // data_size is defined elsewhere
boost::array<asio::mutable_buffer, 3> bufs = {
    asio::buffer(&i, 4), 
    asio::buffer(&s, 2),
    asio::buffer(data, data_size)
};
asio::read(socket, buffer(bufs)); // socket defined elsewhere

2)您已经引用了这个问题的很好答案: “如何使用 Boost::asio 异步读取 std::string?”

1) alternatives can be found by checking asio::buffer() function, overloads that return mutable_buffers_1. more flexible (but probably sub-optimal) option is asio::streambuf, useful for (async_)read_until.

if you have fixed-size fields protocol you can use array of asio::mutable_buffer. e.g.

using boost::asio;
int i;
short s;
char data[data_size]; // data_size is defined elsewhere
boost::array<asio::mutable_buffer, 3> bufs = {
    asio::buffer(&i, 4), 
    asio::buffer(&s, 2),
    asio::buffer(data, data_size)
};
asio::read(socket, buffer(bufs)); // socket defined elsewhere

2) you already referenced great answer to this question: "How to asynchronously read to std::string using Boost::asio?"

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文