2
votes

visual studio tells me "error C2664: 'boost::asio::mutable_buffer::mutable_buffer(const boost::asio::mutable_buffer&)': impossible to convert parameter 1 from 'char' to 'const boost::asio::mutable_buffer&' at line 163 of consuming_buffers.hpp"

I am unsure of why this happen nor how to solve it(otherwise I wouldn't ask this ^^') but I think it could be related to those functions.. even tough I tried them in another project and everything worked fine... but I can hardly find what's different

so... here comes code that could be relevant, if anything useful seems to be missing I'll be glad to send it.

packets are all instances of this class.

class CPacketBase
{
protected:
 const unsigned short _packet_type;
 const size_t _size;
 char* _data;

public:
 CPacketBase(unsigned short packet_type, size_t size);
 ~CPacketBase();

 size_t get_size();
 const unsigned short& get_type();
 virtual char* get();
 virtual void set(char*);
};

this sends a given packet

    template <typename Handler> 
 void async_write(CPacketBase* packet, Handler handler)
 {
  std::string outbuf;
  outbuf.resize(packet->get_size());
  outbuf = packet->get();
  boost::asio::async_write( _socket
   , boost::asio::buffer(outbuf, packet->get_size())
   , handler);
 }

this enable reading packets and calls a function that decodes the packet's header(unsigned short) and resize the buffer to send it to another function that reads the real data from the packet

template <typename Handler> 
 void async_read(CPacketBase* packet, Handler handler)
 {
  void (CTCPConnection::*f)( const boost::system::error_code&
      , CPacketBase*, boost::tuple<Handler>)
       = &CTCPConnection::handle_read_header<Handler>;
  boost::asio::async_read(_socket, _buffer_data
   , boost::bind( f
    , this
    , boost::asio::placeholders::error
    , packet
    , boost::make_tuple(handler)));
 }

and this is called by async_read once a packet is received

template <typename Handler> 
 void handle_read_header(const boost::system::error_code& error, CPacketBase* packet, boost::tuple<Handler> handler)
 {
  if (error)
  {
   boost::get<0>(handler)(error);
  }
  else
  {
   // Figures packet type
   unsigned short packet_type = *((unsigned short*) _buffer_data.c_str());

   // create new packet according to type
   delete packet;
   ...

   // read packet's data
   _buffer_data.resize(packet->get_size()-2); // minus header size

   void (CTCPConnection::*f)( const boost::system::error_code&
     , CPacketBase*, boost::tuple<Handler>)
       = &CTCPConnection::handle_read_data<Handler>;
   boost::asio::async_read(_socket, _buffer_data
    , boost::bind( f
     , this
     , boost::asio::placeholders::error
     , packet
     , handler));
  }
 }
1
commenting boost::asio::async_read call makes me able to build the project once, and then even if I uncomment it I can still build the solution but rebuild gives me different errors: "'const iterator' : is not member of 'boost::asio::mutable_buffer'" "'syntax error: missing ',' before 'const_iterator'"Simon Kérouack
What is the type of _buffer_data in your call to boost::asio::async_read?bjlaub
I tried std::string, std::vector<char> and boost::array<char>, but they don't necessarily place all their data in the same memory areas, which was the problem's source apparentlySimon Kérouack

1 Answers

3
votes

Based on this line of code...

unsigned short packet_type = *((unsigned short*) _buffer_data.c_str());

...I'm guessing you are using a std::string as the type for _buffer_data and attempting to read data into it using boost::asio::async_read. You can't do that (see my answer here for an explanation: How to asynchronously read to std::string using Boost::asio?)

You could try using one of the factory overloads of boost::asio::buffer and using a POD type such as char *. For example:

char * _buffer_data = new char[packet->get_size()-2];
boost::asio::async_read(
    _socket, 
    boost::asio::buffer(_buffer_data, packet->get_size()-2), 
    //....

(I've not tested this, but in theory it should create a mutable buffer wrapping a raw char array that has at most packet->get_size()-2 bytes. Makes sense...)

You could also try using a boost::shared_array<char> instead, but I'm not sure that can be implicitly converted to a mutable buffer either, so you'd have to roll your own "mutable buffer." Note that since boost::asio::async_read is a template function, the second parameter's type is not strictly defined, and can actually be anything that adheres to the mutable buffers concept. See this page for more info on that: http://www.boost.org/doc/libs/1_43_0/doc/html/boost_asio/reference/MutableBufferSequence.html