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?
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.