阻止强制制作我的回调处理程序的副本

时间:2010-08-12 11:21:30

标签: c++ boost-asio

我使用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()中设置断点,我可以检查并比较这个指针。似乎boost :: asio正在复制我的处理程序,在那里调用operator()并返回。我的原始处理程序从未被触及过。

增强文档说,副本将根据需要由处理程序组成。所以这似乎没问题,但我能做些什么来达到理想的行为?

感谢您的帮助

1 个答案:

答案 0 :(得分:1)

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

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

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