15

I get the following error message when I'm trying to use std::string with boost::asio::buffer:

boost/asio/detail/consuming_buffers.hpp:
In constructor
'boost::asio::detail::consuming_buffers<
        boost::asio::mutable_buffer, boost::asio::const_buffers_1
    >::consuming_buffers(const boost::asio::const_buffers_1 &)':
boost/asio/impl/read.hpp:140:25:  
instantiated from
'boost::asio::detail::read_op<
        boost::asio::basic_stream_socket<boost::asio::ip::tcp>,
boost::asio::const_buffers_1
      , boost::asio::detail::transfer_all_t
      , boost::_bi::bind_t<
            void, boost::_mfi::mf1<void, read_op, const
boost::system::error_code &>
          , boost::_bi::list2<boost::_bi::value<read_op
*>, boost::arg<1> (*)()> 
        > 
    >::read_op(
        boost::asio::basic_stream_socket<boost::asio::ip::tcp>
&, const boost::asio::const_buffers_1
&
      , boost::asio::detail::transfer_all_t
      , boost::_bi::bind_t<
            void, boost::_mfi::mf1<void, read_op, const
boost::system::error_code &>
          , boost::_bi::list2<boost::_bi::value<read_op
*>, boost::arg<1> (*)()>
        >
    )'

[...]

Full source code: http://liveworkspace.org/code/eca749f6f2714b7c3c4df9f26a404d86

Joel Bodenmann
  • 2,152
  • 2
  • 17
  • 44
niXman
  • 1,698
  • 3
  • 16
  • 40
  • look at this if you after 2 years are still curious : http://stackoverflow.com/questions/2790383/how-to-asynchronously-read-to-stdstring-using-boostasio – NoSenseEtAl Jul 31 '12 at 16:17

3 Answers3

15

I think the problem is that you are passing a const buffer to async_read instead of a mutable buffer. In the block ending in line 50, boost::asio::buffer(_header) returns a const buffer. You should do something like boost::asio::async_read(s, boost::asio::buffer(data, size), handler), because boost::asio::buffer(data, size) creates a mutable buffer.

Instead of using std::strings for _header and _data, you probably need to use arrays of char, such as:

char* _data;
boost::asio::buffer(_data, strlen(_data));

See reference documentations for buffer and async_read.

Joel Bodenmann
  • 2,152
  • 2
  • 17
  • 44
rturrado
  • 7,699
  • 6
  • 42
  • 62
  • 2
    I'm pretty sure std::strings can be assigned to char* arrays, and one can export the char* array from the std::string with std::string.c_str() – Tom Johnson Apr 25 '11 at 16:45
  • 1
    `std::string::c_str()` returns `const char*` not `char*`. It can only be used with `const_buffer`. – Benjamin Buch Feb 28 '18 at 15:46
7

From the boost::asio::buffer reference documentation:

It seems that std::string could only be passed into an asio::buffer as a const reference.

std::vector<char> should be a better alternative:

std::vector<char> d2(128);
bytes_transferred = sock.receive(boost::asio::buffer(d2));
Joel Bodenmann
  • 2,152
  • 2
  • 17
  • 44
Gang YIN
  • 2,509
  • 2
  • 21
  • 25
7

You must pass a pointer as the first parameter:

#include <string>
#include <boost/asio.hpp>

std::string request, reply;
auto rsize = boost::asio::buffer(&reply[0], request.size());
xunzhang
  • 2,838
  • 6
  • 27
  • 44
  • 4
    As a note, until C++11, this is not necessarily correct. Pre-C++11, the char array held by std::string was not guaranteed to be contiguous, which is required by boost::asio::buffer. In practice, every compiler uses a contiguous block of memory, and so this became required behavior in C++11. – Eldritch Cheese Sep 06 '16 at 13:55