【问题标题】:boost::asio::async_read bind compilation errorboost::asio::async_read 绑定编译错误
【发布时间】:2011-06-28 21:18:42
【问题描述】:

我不知道为什么会出现这个错误:

/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

这是我的课: 命令.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:                             

      };                                                              
    }
}   

Command.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;
          }
      }

    }
  }
}

检查代码块上的“** Error pointing this line**”,这是它有问题的地方......不知道为什么,一次又一次地打破我的头......

感谢您的帮助

为了清楚起见,我删除了一些代码,如果您有任何问题,请不要犹豫

【问题讨论】:

    标签: c++ boost bind boost-asio


    【解决方案1】:

    您的完成处理程序签名不正确,请考虑此示例

    #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 足够聪明,不会将errorbytes_transferred 参数传递给绑定的函数指针。 Asio 库的作者有一个detailed blog post 关于在库中使用绑定。值得一读。

    【讨论】:

    • 谢谢!!那是怎么回事,在我看来几乎一样,不是吗?
    • 一个+1的答案,如果可以的话,我会给你一秒钟的博客链接,谢谢,今天又学到了一些东西^^
    【解决方案2】:

    async_* 操作需要不同的回调函数签名:

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

    请更深入地查看文档,了解如何编写和调用此类回调处理程序的一些示例。

    【讨论】:

    • 这是类的shared_ptr:public shared_from_this,它在其他类上运行良好,这不是编译器抱怨的。谢谢
    • 不幸的是我做到了,这就是我不明白的原因......我正在调用一个简单的 void() 函数,我的回调是一个 boost::function.. . 我们真的不能让它更简单:-/ .
    • 不,你没有,请查看this page。有我贴给你的回调签名,不是 void() 函数,它需要两个参数!
    • sry,但这不是文档告诉我的,它可能是错误的,但对我来说它是使用库的来源。如果有一个处理程序的函数签名必须是:在签名前面,我不会猜到参数是可选的......你会吗?
    • 他们是……他们只有在你想要的时候才会出现。但是,Sam 想通了……我不得不将 boost::bind 直接放在 async_read 上,而没有变量来保存它。不知道为什么,但它有效。
    猜你喜欢
    • 2013-12-21
    • 1970-01-01
    • 1970-01-01
    • 2010-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-24
    • 1970-01-01
    相关资源
    最近更新 更多