You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用asio异步读取时boost::bind绑定回调函数报错求助

问题:Asio async_read_some绑定回调时boost::bind报错

代码实现

构造函数与绑定逻辑

#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")
    {
        ... 一些初始化代码 ...
        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));

回调函数实现

void on_receive_(const boost::system::error_code& ec, size_t bytes_transferred)
    {
        boost::mutex::scoped_lock look(mutex_); // 注意:这里拼写错误,应该是lock
        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;
    }

成员变量定义

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;

错误信息

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_]);
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

解决办法

1. 修正error_code类型不匹配问题

报错核心是回调参数的boost::system::error_code和asio占位符传递的std::error_code类型不兼容,根据你使用的Asio版本调整:

  • 若使用独立Asio库:将回调函数的参数改为const std::error_code& ec,与占位符传递的类型保持一致。
  • 若使用Boost.Asio库:确保占位符使用boost::asio::placeholders::error,而非asio::placeholders::error,同时回调参数保留boost::system::error_code。

2. 明确指定重载的回调函数

由于定义了两个同名的on_receive_函数(分别接收error_code+size和string参数),编译器无法自动推断绑定版本,需用强制类型转换明确指定:

修改绑定代码为:

this->serial->async_read_some( 
    asio::buffer(read_buf_raw_, SERIAL_PORT_READ_BUF_SIZE),
    boost::bind(
        // 强制转换为带error_code和size参数的版本
        static_cast<void(SerialCom::*)(const std::error_code&, size_t)>(&SerialCom::on_receive_),
        this, 
        asio::placeholders::error, 
        asio::placeholders::bytes_transferred));

3. 修复次要bug

回调函数中的锁拼写错误:将boost::mutex::scoped_lock look(mutex_);改为boost::mutex::scoped_lock lock(mutex_);,否则会触发额外编译错误。

内容的提问来源于stack exchange,提问作者Kyuhyong You

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 00:22:51