0

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?

1 Answer 1

0

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Yeah the problem was that on_receive_ was overloaded, so taking the address is ambiguous
@sehe The problem is it only works one time. How do you think it can work continuously?
I do. That's a different question, though. In principle I have the answer at least a hundred times on this site. The easiest way to find sure hits is to search for read_loop, readLoop. Do consider posting a more focused question, though
Yeah I found the solution. Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.