【问题标题】:preventing boost from making a copy of a my callback handler防止 boost 复制我的回调处理程序
【发布时间】:2010-08-12 23:27:10
【问题描述】:

我用boost::asio写了一个小tcp客户端,提供如下功能:

typedef boost::function<void(const bs::error_code& errCode, size_t bytesTransferred)> ReadHandler;

void CTcpClient::AsyncRead2(std::vector<char>& data, size_t length, ReadHandler readCompletedCallback)
{
    async_read(m_tcpData->socket, ba::buffer(data, length), readCompletedCallback);
}

我的想法是为我的 TcpClient 类的用户提供异步操作,而不必担心线程处理、io_services 等。

现在从我的 unittest 类中调用上述函数的代码如下所示:

CTestTcpClient 标头

class CTestTcpClient : public ::testing::Test
{
public:
    CTestTcpClient(void);
    virtual ~CTestTcpClient(void);

    struct ReadCompletedHandler
    {
        ReadCompletedHandler() : m_isCompleted(false){};

        void operator()(const boost::system::error_code& errCode, size_t bytesTransferred)
        {
            m_isCompleted = true; // my breakpoint here, checking this pointer
        };

        bool isCompleted(void)
        {
            return m_isCompleted;
        }

    private:
        bool m_isCompleted;
    };

    ReadCompletedHandler m_readHandler;
};

CTestTcpClient 来源

TEST_F(CTestTcpClient, testAsynchronousRead_Success)
{
    CTcpClient client(testService);
    // Skipped code to setup echo server, connecting and sending of data
    // Receive echo
    vector<char> receiveBuffer(TESTDATA_SIZE);

    client.AsyncRead2(receiveBuffer, TESTDATA_SIZE, m_readHandler);

    while (!m_readHandler.isCompleted())
    {
        client.Wait(200);
    }
}

现在问题来了:while 循环永远不会退出,因为 is_completed 标志设置在 m_readHandler 的 copy 中。如果我在处理程序的 operator() 中设置断点,我可以检查并比较 this 指针。似乎 boost::asio 正在复制我的处理程序,在那里调用 operator() 并返回。我原来的处理程序根本没有被碰过。

boost 文档说,将根据需要制作处理程序的副本。所以这似乎没问题,但我能做些什么来实现所需的行为?

感谢您的帮助

【问题讨论】:

  • +1 表示格式正确的问题。

标签: c++ boost-asio


【解决方案1】:

我用于完成处理程序的典型习惯用法是boost::bind 一个成员函数,它使用boost::shared_from_this 确保有问题的对象不会超出范围。这在几乎所有Boost.Asio examples 中也很普遍。

如果您不想更改设计,可以尝试boost::ref,例如:

client.AsyncRead2(receiveBuffer, TESTDATA_SIZE, boost::ref(m_readHandler) );

【讨论】:

  • 我尝试按照您的建议使用 boost::ref,并且效果很好 :-) 有时解决方案非常简单,如果您知道的话.... Sam,感谢您的时间和帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多