ошибка компиляции привязки boost::asio::async_read

Я не могу понять, почему я получаю эту ошибку:

/usr/local/include/boost/asio/impl/read.hpp: In member function ‘void boost::asio::detail::read_op<AsyncReadStream, boost::asio::mutable_buffers_1, CompletionCondition, ReadHandler>::operator()(const boost::system::error_code&, size_t, int) [with AsyncReadStream = boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, CompletionCondition = boost::asio::detail::transfer_at_least_t, ReadHandler = boost::function<void ()(long unsigned int)>]’:
/usr/local/include/boost/asio/impl/read.hpp:263:   instantiated from ‘void boost::asio::async_read(AsyncReadStream&, const MutableBufferSequence&, CompletionCondition, ReadHandler) [with AsyncReadStream = boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, MutableBufferSequence = boost::asio::mutable_buffers_1, CompletionCondition = boost::asio::detail::transfer_at_least_t, ReadHandler = boost::function<void ()(long unsigned int)>]’
src/communicator/protocol/Command.cc:34:   instantiated from here
/usr/local/include/boost/asio/impl/read.hpp:215: error: no match for call to ‘(boost::function<void ()(long unsigned int)>) (const boost::system::error_code&, const long unsigned int&)’
/usr/local/include/boost/function/function_template.hpp:1007: note: candidates are: typename boost::function1<R, T1>::result_type boost::function1<R, T1>::operator()(T0) const [with R = void, T0 = long unsigned int]
make: *** [src/communicator/protocol/Command.o] Error 1

Вот мой класс: Command.hh

namespace communicator {                                              
  namespace protocol {                                                
    namespace in {                                                    
      class Command : public boost::enable_shared_from_this<Command> {
      public:                                                         
        ~Command();                                                   

        typedef boost::shared_ptr<Command>      pointer;              

        void got_newline();                                           

      protected:                                                      
        Command(tcp::socket& socket, structure::Client& client) :     
          m_socket(socket), m_client(client)  {};

        void endParsing();

        tcp::socket&            m_socket;                             

        structure::Client&      m_client;                             
        char                    m_newline[2];                          
      private:                             

      };                                                              
    }
}   

Команда.cc :

namespace   communicator {
    namespace protocol {
    namespace in {

      void Command::endParsing()  {
        boost::function<void()> cb = boost::bind(&Command::got_newline,
                                          shared_from_this());
        boost::asio::async_read(m_socket,
                                boost::asio::buffer(m_newline, 2),
                                boost::asio::transfer_at_least(2),
**ERROR POINTING THIS LINE**                                    cb);
      }

      void Command::got_newline()  {
        if (m_newline[0] == '\r' && m_newline[1] == '\n') {
           std::cout << "End" << std::endl;
          }
      }

    }
  }
}

Проверьте «** Ошибка при указании этой строки **» в блоке кода, здесь есть проблема ... не знаю, почему, ломал голову снова и снова ...

Спасибо за помощь

Я удалил часть кода для ясности, если у вас есть какие-либо вопросы, не стесняйтесь


person TheSquad    schedule 28.06.2011    source источник


Ответы (2)


Ваша подпись обработчика завершения неверна, рассмотрите этот пример

#include <boost/asio.hpp>

#include <boost/function.hpp>
#include <boost/bind.hpp>

void
foo()
{

}

int
main()
{
    boost::asio::io_service io_service;
    boost::asio::ip::tcp::socket socket( io_service );

    char buf[2];

    // this compiles file
    boost::asio::async_read(
            socket,
            boost::asio::buffer(buf),
            boost::asio::transfer_at_least(2),
            boost::bind( &foo )
            );

    // this does not
    boost::function<void()> cb = boost::bind( &foo );
    boost::asio::async_read(
            socket,
            boost::asio::buffer(buf),
            boost::asio::transfer_at_least(2),
            cb
            );

}

boost::bind достаточно умен, чтобы не передавать параметры error или bytes_transferred указателю связанной функции. У автора библиотеки Asio есть подробный пост об использовании связать с библиотекой. Это стоит прочитать.

person Sam Miller    schedule 28.06.2011
comment
Спасибо !! И как это, мне кажется, почти то же самое, не так ли? - person TheSquad; 29.06.2011
comment
один +1 за ответ, и если бы я мог, я бы дал вам секунду за ссылку на сообщение в блоге, спасибо, сегодня снова кое-что узнал ^^ - person Thomas Berger; 29.06.2011

Операции async_* требуют другой подписи для функции обратного вызова:

void handler(
  const boost::system::error_code& error, // Result of operation.
  std::size_t bytes_transferred           // Number of bytes read.
); 

Пожалуйста, внимательно изучите документацию для некоторых примеров того, как написать и вызвать такой обработчик обратного вызова.

person Thomas Berger    schedule 28.06.2011
comment
Это shared_ptr класса: public shared_from_this‹›, он хорошо работает на других классах, и компилятор жалуется не на это. Спасибо - person TheSquad; 29.06.2011
comment
К сожалению, я это сделал, и вот почему я не понимаю... Я вызываю простую функцию void(), и мой обратный вызов - это boost::function‹void()›... Мы действительно не можем это сделать проще :-/ . - person TheSquad; 29.06.2011
comment
нет, посмотрите на эта страница. Я отправил вам сигнатуру обратного вызова, а НЕ функцию void(), она ожидает два параметра! - person Thomas Berger; 29.06.2011
comment
извините, но это не то, что говорит мне документация, это может быть неправильно, но для меня это источник для использования библиотеки. И если есть Сигнатура функции обработчика должна быть: перед подписью, я бы не догадался, что параметры необязательны... а вы? - person Thomas Berger; 29.06.2011
comment
Они... Они есть, только если ты этого хочешь. Тем не менее, Сэм понял это... Мне пришлось добавить boost::bind непосредственно к async_read, не имея переменной для его хранения. Не уверен, почему, но это работает. - person TheSquad; 29.06.2011