1

ここでの問題は非常に一般的だと思いますが、ここで何が間違っているのかよくわかりません。

私はいくつかのboost::asioのことをやっていて、テンプレート化された非同期読み取り関数を書き込もうとしています。

ここに関数があります。

template <typename Handler>
void AsyncRead(std::vector<boost::uint8_t>& _inMsg, Handler _handler)
{
    #if debug
      std::cout<< "IConnection::AsyncRead" << std::endl;
    #endif
    using namespace protocols;

    typedef boost::tuple<Handler> tHandler;
    typedef boost::function< void(const boost::system::error_code &, std::vector<boost::uint8_t> &, tHandler ) > HeaderReaderFunc;

    //void (AConnection::*f)(const boost::system::error_code&, std::vector<boost::uint8_t>&, boost::tuple<Handler>) = &AConnection::HandleReadHeader<Handler>;


    tHandler t(boost::make_tuple(_handler));
    HeaderReaderFunc x(boost::bind(&AConnection::HandleReadHeader<Handler>, this, boost::asio::placeholders::error, boost::ref(_inMsg), t));
    inboundHeader.resize(sizeof(SocketIO::MsgData));
    boost::asio::async_read(socket, boost::asio::buffer(inboundHeader), x);

}

この関数の最後のステートメントで事態が悪化し始めます。

boost::asio::async_read(socket, boost::asio::buffer(inboundHeader), x);

変数 'x' をパラメーターとして async_read 関数に渡そうとしたとき。

エラーは、長さと解読可能な意味の欠如の両方で伝説的です。

エラー出力のほんの一例:

boost_1_38_0/boost/asio/detail/bind_handler.hpp: In member function ‘void boost::asio::detail::binder2<Handler, Arg1, Arg2>::operator()() [with Handler =  boost::function<void ()(const boost::system::error_code&, std::vector<unsigned char, std::allocator<unsigned char> >&, boost::tuples::tuple<boost::function<void ()(const boost::system::error_code&)>, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>)>, Arg1 = boost::system::error_code, Arg2 = unsigned int]’:

ここでブースト関数を使用せず、代わりにメンバー関数への参照であるコメントアウトされた行を使用すると、うまくいくように見えますが、その理由を特定することはできません。

AConnection::HandleReadHeader 関数テンプレートの関数シグネチャは次のとおりです。

template <typename Handler>
void HandleReadHeader(const boost::system::error_code& _e,
                    std::vector<boost::uint8_t> & _inMsg, 
                    boost::tuple<Handler> _handler)

ハンドラーのタイプは次のとおりです。

    boost::function<void (const boost::system::error_code & ) >

関数 AsyncRead と HandleReadHeader は、私自身のクラス AConnection のメンバーです (おそらく重要ではありません)。

署名にboost::tupleが含まれるboost::functionオブジェクトの作成に関する構文に関する何かが欠けているか、boost::asio::async_read関数の3番目のパラメータータイプが変数 'xと一致していません'。

どんな助けでも大歓迎です。ありがとうございました。

編集:

これは機能しますが、boost::functon の代わりにメンバー関数参照を使用するコードです。

template <typename Handler>
void AsyncRead(std::vector<boost::uint8_t>& _inMsg, Handler _handler)
{
 #if debug
   std::cout<< "Connection::AsyncRead" << std::endl;
 #endif
 using namespace protocols;
 // Issue a read operation to read exactly the number of bytes in a header.
 void (Connection::*f)(
     const boost::system::error_code&,
     std::vector<boost::uint8_t>&, boost::tuple<Handler>)
   = &Connection::HandleReadHeader<Handler>;

 inboundHeader.resize(sizeof(simple::message_header));
 boost::asio::async_read(socket, boost::asio::buffer(inboundHeader),
     boost::bind(f,
     this, boost::asio::placeholders::error, boost::ref(_inMsg),
     boost::make_tuple(_handler)));
}
4

1 に答える 1

0

変数xには次のタイプがあります。

boost::function< void(const boost::system::error_code &,
    std::vector<boost::uint8_t> &, boost::tuple<Handler>) >

これは、次の署名に似ています。

void handler(const boost::system::error_code &,
    std::vector<boost::uint8_t> &, boost::tuple<Handler>)

それでも、Boost Asio のドキュメントでは、ハンドラーの署名は次のようにする必要があります。

void handler(const boost::system::error_code&,
    std::size_t bytes_transferred)

したがって、あなたの署名は一致しません。Boost ドキュメントで見つけることができなかったオーバーロードを使用しているか、async_read が期待するものと一致するように HeaderReaderFunc タイプを変更する必要があります。

于 2012-01-21T04:53:25.077 に答える