views:

313

answers:

2

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));
  }
 }
A: 

The error:

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

means that you're passing a char variable where a const boost::asio::mutable_buffer& is expected.

In others words, in this case, you call the copy constructor of boost::asio::mutable_buffer with a char where it would expect another instance of boost::asio::mutable_buffer.

I can't see in the code you posted any reference to boost::asio::mutable_buffer. However, since I don't know asio, my understanding of the code you posted might be unsufficient to give a cleaner explanation.

ereOn
the 2nd parameter of boost's async operations are the only possible references to boost::asio::mutable_buffer I can see in my code even tough it's not explicit.. . which makes it even harder to find the actual error for me... thanks anyway ^^but indeed, I tried to use std::string, char[], std::vector<char> and a few other containers as buffers. they all worked fine when I tried them in other projects, but I always get this error in this one...I think the problem is in the async_read function, but I still can't solve it
Ekyo777
@Ekyo777: Reading the `boost::asio` documentation, the 2nd parameter of boost's async operations must be "convertible to muttable buffer". Here is a link which *might* help. http://www.boost.org/doc/libs/1_35_0/doc/html/boost_asio/reference/ConvertibleToMutableBuffer.html
ereOn
I tried declaring my buffer this way.. and I hope it can be converted to a mutable buffer since it is one... and the problem's still here. std::vector<char> _buffer_data; _buffer_data.resize(2); boost::asio::mutable_buffer buffer = boost::asio::buffer<char>(_buffer_data);
Ekyo777
A: 

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: http://stackoverflow.com/questions/2790383/how-to-asynchronously-read-to-stdstring-using-boostasio/2795371#2795371)

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

bjlaub
totally works, thanks ;)also explains why std::vector<char> arrays didn't work...and I think it worked in my other project because I never resized my arrays...well, thanks ^_^
Ekyo777