I figure my issue here is very common, but I just can't quite see what I'm doing wrong here.
I'm doing some boost::asio stuff and attempting to write a templated asynchronous read function.
Here is a function.
template <typename Handler>
void AsyncRead(std::vector<boost::uint8_t>& _inMsg, Handler _handler)
{
#if debug
std::cout<< "IConnection::AsyncRead" << std::endl;
#endif
using namespace protocols;
typedef boost::tuple<Handler> tHandler;
typedef boost::function< void(const boost::system::error_code &, std::vector<boost::uint8_t> &, tHandler ) > HeaderReaderFunc;
//void (AConnection::*f)(const boost::system::error_code&, std::vector<boost::uint8_t>&, boost::tuple<Handler>) = &AConnection::HandleReadHeader<Handler>;
tHandler t(boost::make_tuple(_handler));
HeaderReaderFunc x(boost::bind(&AConnection::HandleReadHeader<Handler>, this, boost::asio::placeholders::error, boost::ref(_inMsg), t));
inboundHeader.resize(sizeof(SocketIO::MsgData));
boost::asio::async_read(socket, boost::asio::buffer(inboundHeader), x);
}
Things start going bad in the last statement of this function.
boost::asio::async_read(socket, boost::asio::buffer(inboundHeader), x);
When I attempt to pass the variable 'x' as a parameter into the async_read function.
The errors are legendary in both length and lack of decipherable meaning.
Just a small example of error output:
boost_1_38_0/boost/asio/detail/bind_handler.hpp: In member function ‘void boost::asio::detail::binder2<Handler, Arg1, Arg2>::operator()() [with Handler = boost::function<void ()(const boost::system::error_code&, std::vector<unsigned char, std::allocator<unsigned char> >&, boost::tuples::tuple<boost::function<void ()(const boost::system::error_code&)>, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>)>, Arg1 = boost::system::error_code, Arg2 = unsigned int]’:
If I do not use boost function here, and instead use the commented out line which is a reference to a member function, things seem to work, but I can't put my finger on why that is.
The function signature for the AConnection::HandleReadHeader function template is:
template <typename Handler>
void HandleReadHeader(const boost::system::error_code& _e,
std::vector<boost::uint8_t> & _inMsg,
boost::tuple<Handler> _handler)
Handler is of type:
boost::function<void (const boost::system::error_code & ) >
The functions AsyncRead and HandleReadHeader are members of my own class AConnection (probably not important).
Either I'm missing something regarding the syntax in regard to creating a boost::function object who's signature includes a boost::tuple, or the boost::asio::async_read function's third parameter type is not being matched by my variable 'x'.
Any help would be appreciated. Thank you.
EDIT:
Here is code that does work, but uses a member function reference instead of a boost::functon.
template <typename Handler>
void AsyncRead(std::vector<boost::uint8_t>& _inMsg, Handler _handler)
{
#if debug
std::cout<< "Connection::AsyncRead" << std::endl;
#endif
using namespace protocols;
// Issue a read operation to read exactly the number of bytes in a header.
void (Connection::*f)(
const boost::system::error_code&,
std::vector<boost::uint8_t>&, boost::tuple<Handler>)
= &Connection::HandleReadHeader<Handler>;
inboundHeader.resize(sizeof(simple::message_header));
boost::asio::async_read(socket, boost::asio::buffer(inboundHeader),
boost::bind(f,
this, boost::asio::placeholders::error, boost::ref(_inMsg),
boost::make_tuple(_handler)));
}
Your variable
x
has this type:Which is similar to this signature:
Yet, the Boost Asio docs say the handler signature should be this:
So, your signatures do not match--not even close. Either you are using some overload I wasn't able to find in the Boost docs, or you need to change the HeaderReaderFunc type to match what async_read expects.