c++boostbindasio

boost bind error for async reading with asio


I am trying to bind a callback function with asio async_read_some function.

Here is the code I tried to bind callback function for async reading.

#include <chrono>
#include <iostream>
#include <asio.hpp>
#include <asio/io_service.hpp>
#include <asio/serial_port.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>

class SerialCom : public rclcpp::Node
{
public:
    SerialCom() : Node("serial_com_node")
    {
        ... Some initializations...
        boost::thread t(boost::bind(&asio::io_service::run, io_service));
        if (this->serial == NULL || !this->serial->is_open()) return;
        this->serial->async_read_some( 
            asio::buffer(read_buf_raw_, SERIAL_PORT_READ_BUF_SIZE),
            boost::bind(
                &SerialCom::on_receive_,
                this, 
                asio::placeholders::error, 
                asio::placeholders::bytes_transferred));

This is how on_receive_ functions are written

    void on_receive_(const boost::system::error_code& ec, size_t bytes_transferred)
    {
        boost::mutex::scoped_lock look(mutex_);
        if (this->serial == NULL || !this->serial->is_open()) return;
        if (ec) {
            async_read_some_();
            return;
        }
        for (unsigned int i = 0; i < bytes_transferred; ++i) {
            char c = read_buf_raw_[i];
            if (c == end_of_line_char_) {
                this->on_receive_(read_buf_str_);
                read_buf_str_.clear();
            } else {
                read_buf_str_ += c;
            }
        }
        async_read_some_();
    }

    void on_receive_(const std::string &data)
    {
        std::cout << "SerialPort::on_receive_() : " << data << std::endl;
    }

Here are some member variables

    std::string port_name_;
    int baudrate_;
    int pub_rate_;
    int output_hz_;
    std::shared_ptr<asio::io_service> io_service;
    std::shared_ptr<asio::serial_port> serial;
    char end_of_line_char_;
    char read_buf_raw_[SERIAL_PORT_READ_BUF_SIZE];
    std::string read_buf_str_;
    boost::mutex mutex_;
    std::chrono::milliseconds timer_ms;

I am getting error like below This looks like boost::bind used incorrectly.

src/serial_node.cpp:103:55:   required from here
/usr/include/boost/bind/bind.hpp:398:35: error: no match for call to ‘(boost::_mfi::mf2<void, SerialCom, const boost::system::error_code&, long unsigned int>) (SerialCom*&, const std::error_code&, const long unsigned int&)’
  398 |         unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_]);
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Any suggestions?


Solution

  • I somehow managed to successfully compile by using below code

        void start_receive()
        {
            this->serial->async_read_some(
                boost::asio::buffer(rx_buf),
                boost::bind(&SerialCom::on_receive_,
                    this, 
                    boost::asio::placeholders::error,
                    boost::asio::placeholders::bytes_transferred));
            this->io_service->run();
        }
    
        void on_receive_(const boost::system::error_code& error,
            std::size_t bytes_transferred)
        {
            if(!error) {
                std::cout << "Received: " << rx_buf <<", "<<bytes_transferred<< std::endl;
            } else {
                std::cout << "Error receive"<<std::endl;
            }
        }
    

    Now I can read some bytes from the serial however it stops reading when rx_buf is filled.