2012-12-22 34 views
6

Tôi đang sử dụng asio tăng cường trong suốt dự án của mình. Bây giờ tôi muốn đọc một tập tin thiết bị (/dev/input/eventX). Trong tài liệu asio tăng, nó cho biết tệp IO bình thường là không thể nhưng tệp thiết bị hoặc đường ống được hỗ trợ bằng cách sử dụng asio::posix::stream_descriptor.cách sử dụng asio với các tệp thiết bị

Tôi đã mở bộ mô tả tệp qua mở và gán nó cho stream_descriptor. Tôi hiện đang phát hành cuộc gọi async_read() không bao giờ trả lại.

Có thể sử dụng asio tăng cường với các sự kiện đầu vào không? Tôi có cần phải cấu hình xử lý tập tin trước khi sử dụng nó với asio qua ioctl?

Chỉnh sửa: Thêm một số mã mẫu -> đã thêm một số mã mẫu.

Đoạn mã sau mở/dev/input/event12 và phương thức chạy trên đối tượng io_service được gọi.

#include <boost/asio.hpp> 
#include <string> 
#include <iostream> 
#include <boost/bind.hpp> 
#include <linux/input.h> 

namespace asio = boost::asio; 
#ifdef BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR 
typedef asio::posix::stream_descriptor stream_descriptor; 
#else // BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR 
typedef asio::windows::stream_handle stream_descriptor; 
#endif // BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR 

class FileReader 
{ 
    typedef boost::shared_ptr<asio::streambuf> StreambufPtr; 
    typedef boost::shared_ptr<FileReader> FileReaderPtr; 
    typedef boost::weak_ptr<FileReader> FileReaderWeakPtr; 
    public: 
    static FileReaderWeakPtr Create(asio::io_service& io_service, const std::string& path); 
    virtual ~FileReader(); 

    void HandleRead(FileReaderPtr me, StreambufPtr sb, 
        const boost::system::error_code &error); 
private: 
    FileReader(asio::io_service& io_service, const std::string& path); 
    stream_descriptor m_InputStream; 
}; 

FileReader::FileReaderWeakPtr FileReader::Create(asio::io_service& io_service, 
               const std::string& path){ 
    FileReaderPtr ptr(new FileReader(io_service, path)); 
    StreambufPtr sb(new boost::asio::streambuf()); 

    asio::async_read(ptr->m_InputStream, *sb, 
      boost::bind(&FileReader::HandleRead, ptr.get(), 
      ptr, sb, asio::placeholders::error)); 
    return ptr; 
} 

FileReader::FileReader(asio::io_service& io_service, const std::string& path) 
    :m_InputStream(io_service) 
{ 
    int dev = open(path.c_str(), O_RDONLY); 
    if (dev == -1) { 
     throw std::runtime_error("failed to open device " + path); 
    } 

    m_InputStream.assign(dev); 
} 

void FileReader::HandleRead(FileReaderPtr me, StreambufPtr sb, 
        const boost::system::error_code &error) { 
    if(!error) { 
     //Inform all of a sucessfull read 
     std::istream is(sb.get()); 
     size_t data_length = sb->size(); 
     asio::async_read(m_InputStream, *sb, 
      boost::bind(&FileReader::HandleRead, this, me, sb, asio::placeholders::error)); 
    } 
} 
+0

Cuộc gọi đến async_read() không trả về hoặc bạn có nghĩa là cuộc gọi lại không được gọi? Nếu không có mã thì thật khó để chẩn đoán. Bạn có nhớ gọi io_service :: run() không? Đối với những gì nó có giá trị, tôi đã thực hiện chính xác điều này và nó chắc chắn hoạt động. – Sean

+0

@sean Gọi lại không bao giờ được gọi là bắt chước. –

Trả lời

3

Vấn đề là tôi đang sử dụng async_read mà không có bất kỳ điều kiện hoàn chỉnh nào. Do đó cuộc gọi lại không bao giờ được gọi. Sau khi thay đổi cuộc gọi thành async_read_some, mọi thứ hoạt động như mong đợi.

+2

_Sau khi thay đổi cuộc gọi đến async_read_some_ không thực sự giúp đỡ bất cứ ai. Bạn nên viết một số mã với sự thay đổi tương ứng. – Victor

Các vấn đề liên quan