首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >c++ boost asio串行通信在basic_serial_port.hpp中“不能访问私有成员”

c++ boost asio串行通信在basic_serial_port.hpp中“不能访问私有成员”
EN

Stack Overflow用户
提问于 2013-04-26 08:38:01
回答 1查看 1.5K关注 0票数 1

我正在编写一个C++程序,通过COM端口与多个设备-- Arduino Pro Mini w/ATmega328 328和带有全球定位系统屏蔽的Arduino Uno --同时通信,我使用的是boost::asio包。我不是C++大师,所以我偶尔会弄糊涂,试图找出什么地方/什么时候传递引用或值;我认为这就是其中之一。

下面是设置串行通信端口的代码

代码语言:javascript
复制
std::string IMU_COM_PORT = "COM5"; // or whatever... it varies
int IMU_BAUD_RATE = 57600;
std::string ARDUINO_COM_PORT = "COM3"; // also varies
int ARDUINO_BAUD_RATE = 115200;

int main() {
    std::vector<boost::thread *> sensorThreads;
    int sensorThreadCount = 0;

    using namespace::boost::asio;

    // get the COM port handle for the IMU sensor
    boost::asio::io_service IMU_io;
    boost::asio::serial_port IMU_port(IMU_io);
    IMU_port.open(IMU_COM_PORT);
    if (!IMU_port.is_open()) {
        cerr << "Failed to connect to IMU." << endl;
    }
    else {
        IMU_port.set_option(boost::asio::serial_port_base::baud_rate(IMU_BAUD_RATE));
        // the IMU has to be put into triggered output mode with a specific command: #o0
        // to put it back into continuous output mode we can use this command: #o1
        std::string IMU_init_cmd = "#o0";
        boost::asio::write(IMU_port, boost::asio::buffer(IMU_init_cmd.c_str(), IMU_init_cmd.size()));
        // now the IMU should be ready

        sensorThreads.push_back(new boost::thread(testIMUThread, IMU_port));
        sensorThreadCount++;
    }

    // get the COM port handle for the ARDUINO board with GPS sensor
    boost::asio::io_service ARDUINO_io;
    boost::asio::serial_port ARDUINO_port(ARDUINO_io);
    ARDUINO_port.open(ARDUINO_COM_PORT);
    if (!ARDUINO_port.is_open()) {
        cerr << "Failed to connect to ARDUINO." << endl;
    }
    else {
        ARDUINO_port.set_option(boost::asio::serial_port_base::baud_rate(ARDUINO_BAUD_RATE));
        // now the ARDUINO w/GPS sensor should be ready

        sensorThreads.push_back(new boost::thread(testGPSThread, ARDUINO_port));
        sensorThreadCount++;
    }

    for (int i = 0; i < sensorThreadCount; i++) {
        sensorThreads[i]->join();
        delete sensorThreads[i];
    }
}

我的两个测试线程函数基本上是相同的,唯一的区别是它们发送给设备的字节(S)表示有什么东西(我的计算机)正在等待从它们读取数据。

代码语言:javascript
复制
void testIMUThread(boost::asio::serial_port *port) {
    while(true) { cout << readCOMLine(port, "#f") << endl; }
}
void testGPSThread(boost::asio::serial_port *port) {
    while(true) { cout << readCOMLine(port, "r") << endl; }
}

这两个测试线程都使用了一个执行串行读写的函数。

代码语言:javascript
复制
std::string readCOMLine(boost::asio::serial_port *port, std::string requestDataCmd) {
    char c;
    std::string s;
    boost::asio::write(port, boost::asio::buffer(requestDataCmd.c_str(), requestDataCmd.size()));
    while(true) {
        boost::asio::read(port, boost::asio::buffer(&c,1));
        switch(c) {
            case '\r': break;
            case '\n': return s;
            default: s += c;
        }
    }
}

上面的代码不编译,而是生成以下内容(在MSVC2010中):Error 11 error C2248: 'boost::asio::basic_io_object<IoObjectService>::basic_io_object' : cannot access private member declared in class 'boost::asio::basic_io_object<IoObjectService>' C:\boost_1_51_0\boost\asio\basic_serial_port.hpp

这条错误信息对我没有帮助--至少对我来说--因为我还没有找到根本原因。我在这里错过了什么?

谢谢你的帮助。

编辑:解决方案(感谢山姆·米勒)

使用按引用传递(即boost::ref())

代码语言:javascript
复制
sensorThreads.push_back(new boost::thread(testIMUThread, IMU_port));
sensorThreads.push_back(new boost::thread(testIMUThread, ARDUINO_port));

main()变成

代码语言:javascript
复制
sensorThreads.push_back(new boost::thread(testIMUThread, boost::ref(IMU_port)));
sensorThreads.push_back(new boost::thread(testIMUThread, boost::ref(ARDUINO_port)));

然后将工作马和线程函数按如下方式修改

代码语言:javascript
复制
std::string readCOMLine(boost::asio::serial_port &port, std::string requestDataCmd) {
    char c;
    std::string s;
    boost::asio::write(port, boost::asio::buffer(requestDataCmd.c_str(), requestDataCmd.size()));
    while(true) {
        boost::asio::read(port, boost::asio::buffer(&c,1));
        switch(c) {
            case '\r': break;
            case '\n': return s;
            default: s += c;
        }
    }
}
void testIMUThread(boost::asio::serial_port &port) {
    while(true) { cout << readCOMLine(port, "#f") << endl; }
}
void testGPSThread(boost::asio::serial_port &port) {
    while(true) { cout << readCOMLine(port, "r") << endl; }
}

另一方面,如果使用按指针传递,则main()中的线程初始化如下所示

代码语言:javascript
复制
sensorThreads.push_back(new boost::thread(testIMUThread, &IMU_port));
sensorThreads.push_back(new boost::thread(testIMUThread, &ARDUINO_port));

线程的功能如下

代码语言:javascript
复制
void testIMUThread(boost::asio::serial_port *port) {
    while(true) { cout << readCOMLine(port, "#f") << endl; }
}
void testGPSThread(boost::asio::serial_port *port) {
    while(true) { cout << readCOMLine(port, "r") << endl; }
}

但是,我必须对完成所有工作的函数(即读/写调用)进行一些额外的更改(在修改输入参数的基础上)。

代码语言:javascript
复制
std::string readCOMLine(boost::asio::serial_port *port, std::string requestDataCmd) {
    char c;
    std::string s;
    port->write_some(boost::asio::buffer(requestDataCmd.c_str(), requestDataCmd.size())); // this line
    while(true) {
        port->read_some(boost::asio::buffer(&c,1)); // and this line
        switch(c) {
            case '\r': break;
            case '\n': return s;
            default: s += c;
        }
    }
}

这两种解决方案都是编译的,而且似乎都符合我的目的。

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-04-26 16:27:22

boost::asio::serial_port对象不可复制

你应该传递一个引用

代码语言:javascript
复制
sensorThreads.push_back(new boost::thread(testIMUThread, boost::ref(IMU_port)));

或者一个指针

代码语言:javascript
复制
sensorThreads.push_back(new boost::thread(testIMUThread, &IMU_port));

这里有一个柯尔鲁,显示了这两种方法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16232088

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档