boost::asio 缓冲区不可能将参数从 char 转换为 const mutable_buffer&

发布于 2024-09-04 15:54:39 字数 2495 浏览 6 评论 0原文

Visual Studio 告诉我“错误 C2664: 'boost::asio::mutable_buffer::mutable_buffer(const boost::asio::mutable_buffer&)':无法将参数 1 从 'char' 转换为 'const boost::asio::可变缓冲区&'在 consuming_buffers.hpp 的第 163 行”

我不确定为什么会发生这种情况,也不知道如何解决它(否则我不会问这个 ^^'),但我认为它可能与这些函数有关..即使很难,我也尝试过它们另一个项目,一切工作正常...但我几乎找不到什么不同,

所以...这里有可能相关的代码,如果似乎缺少任何有用的东西,我会很高兴发送它。

数据包都是该类的实例。

class CPacketBase
{
protected:
 const unsigned short _packet_type;
 const size_t _size;
 char* _data;

public:
 CPacketBase(unsigned short packet_type, size_t size);
 ~CPacketBase();

 size_t get_size();
 const unsigned short& get_type();
 virtual char* get();
 virtual void set(char*);
};

这会发送给定的数据包,

    template <typename Handler> 
 void async_write(CPacketBase* packet, Handler handler)
 {
  std::string outbuf;
  outbuf.resize(packet->get_size());
  outbuf = packet->get();
  boost::asio::async_write( _socket
   , boost::asio::buffer(outbuf, packet->get_size())
   , handler);
 }

这会启用读取数据包并调用一个函数来解码数据包的标头(无符号短整型)并调整缓冲区大小以将其发送到另一个从数据包中读取实际数据的函数

template <typename Handler> 
 void async_read(CPacketBase* packet, Handler handler)
 {
  void (CTCPConnection::*f)( const boost::system::error_code&
      , CPacketBase*, boost::tuple<Handler>)
       = &CTCPConnection::handle_read_header<Handler>;
  boost::asio::async_read(_socket, _buffer_data
   , boost::bind( f
    , this
    , boost::asio::placeholders::error
    , packet
    , boost::make_tuple(handler)));
 }

,一旦数据包被读取,就会由 async_read 调用已收到

template <typename Handler> 
 void handle_read_header(const boost::system::error_code& error, CPacketBase* packet, boost::tuple<Handler> handler)
 {
  if (error)
  {
   boost::get<0>(handler)(error);
  }
  else
  {
   // Figures packet type
   unsigned short packet_type = *((unsigned short*) _buffer_data.c_str());

   // create new packet according to type
   delete packet;
   ...

   // read packet's data
   _buffer_data.resize(packet->get_size()-2); // minus header size

   void (CTCPConnection::*f)( const boost::system::error_code&
     , CPacketBase*, boost::tuple<Handler>)
       = &CTCPConnection::handle_read_data<Handler>;
   boost::asio::async_read(_socket, _buffer_data
    , boost::bind( f
     , this
     , boost::asio::placeholders::error
     , packet
     , handler));
  }
 }

visual studio tells me "error C2664: 'boost::asio::mutable_buffer::mutable_buffer(const boost::asio::mutable_buffer&)': impossible to convert parameter 1 from 'char' to 'const boost::asio::mutable_buffer&' at line 163 of consuming_buffers.hpp"

I am unsure of why this happen nor how to solve it(otherwise I wouldn't ask this ^^') but I think it could be related to those functions.. even tough I tried them in another project and everything worked fine... but I can hardly find what's different

so... here comes code that could be relevant, if anything useful seems to be missing I'll be glad to send it.

packets are all instances of this class.

class CPacketBase
{
protected:
 const unsigned short _packet_type;
 const size_t _size;
 char* _data;

public:
 CPacketBase(unsigned short packet_type, size_t size);
 ~CPacketBase();

 size_t get_size();
 const unsigned short& get_type();
 virtual char* get();
 virtual void set(char*);
};

this sends a given packet

    template <typename Handler> 
 void async_write(CPacketBase* packet, Handler handler)
 {
  std::string outbuf;
  outbuf.resize(packet->get_size());
  outbuf = packet->get();
  boost::asio::async_write( _socket
   , boost::asio::buffer(outbuf, packet->get_size())
   , handler);
 }

this enable reading packets and calls a function that decodes the packet's header(unsigned short) and resize the buffer to send it to another function that reads the real data from the packet

template <typename Handler> 
 void async_read(CPacketBase* packet, Handler handler)
 {
  void (CTCPConnection::*f)( const boost::system::error_code&
      , CPacketBase*, boost::tuple<Handler>)
       = &CTCPConnection::handle_read_header<Handler>;
  boost::asio::async_read(_socket, _buffer_data
   , boost::bind( f
    , this
    , boost::asio::placeholders::error
    , packet
    , boost::make_tuple(handler)));
 }

and this is called by async_read once a packet is received

template <typename Handler> 
 void handle_read_header(const boost::system::error_code& error, CPacketBase* packet, boost::tuple<Handler> handler)
 {
  if (error)
  {
   boost::get<0>(handler)(error);
  }
  else
  {
   // Figures packet type
   unsigned short packet_type = *((unsigned short*) _buffer_data.c_str());

   // create new packet according to type
   delete packet;
   ...

   // read packet's data
   _buffer_data.resize(packet->get_size()-2); // minus header size

   void (CTCPConnection::*f)( const boost::system::error_code&
     , CPacketBase*, boost::tuple<Handler>)
       = &CTCPConnection::handle_read_data<Handler>;
   boost::asio::async_read(_socket, _buffer_data
    , boost::bind( f
     , this
     , boost::asio::placeholders::error
     , packet
     , handler));
  }
 }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

高跟鞋的旋律 2024-09-11 15:54:39

基于这行代码...

unsigned short packet_type = *((unsigned short*) _buffer_data.c_str());

...我猜您正在使用 std::string 作为 _buffer_data 的类型并尝试将数据读入其中使用boost::asio::async_read。你不能这样做(请参阅我的回答以获取解释:如何使用 Boost::asio 异步读取 std::string?

您可以尝试使用 boost::asio::buffer 的工厂重载之一并使用POD 类型,例如 char *。例如:(

char * _buffer_data = new char[packet->get_size()-2];
boost::asio::async_read(
    _socket, 
    boost::asio::buffer(_buffer_data, packet->get_size()-2), 
    //....

我没有测试过这个,但理论上它应该创建一个可变缓冲区,包装一个最多有 packet->get_size()-2 字节的原始字符数组。这是有道理的。 ..)

您也可以尝试使用 boost::shared_array 来代替,但我不确定它是否可以隐式转换为可变缓冲区,因此您必须滚动您的自己的“可变缓冲区”。请注意,由于 boost::asio::async_read 是一个模板函数,因此第二个参数的类型没有严格定义,实际上可以是遵循可变缓冲区概念的任何类型 。有关详细信息,请参阅此页面: http ://www.boost.org/doc/libs/1_43_0/doc/html/boost_asio/reference/MutableBufferSequence.html

Based on this line of code...

unsigned short packet_type = *((unsigned short*) _buffer_data.c_str());

...I'm guessing you are using a std::string as the type for _buffer_data and attempting to read data into it using boost::asio::async_read. You can't do that (see my answer here for an explanation: How to asynchronously read to std::string using Boost::asio?)

You could try using one of the factory overloads of boost::asio::buffer and using a POD type such as char *. For example:

char * _buffer_data = new char[packet->get_size()-2];
boost::asio::async_read(
    _socket, 
    boost::asio::buffer(_buffer_data, packet->get_size()-2), 
    //....

(I've not tested this, but in theory it should create a mutable buffer wrapping a raw char array that has at most packet->get_size()-2 bytes. Makes sense...)

You could also try using a boost::shared_array<char> instead, but I'm not sure that can be implicitly converted to a mutable buffer either, so you'd have to roll your own "mutable buffer." Note that since boost::asio::async_read is a template function, the second parameter's type is not strictly defined, and can actually be anything that adheres to the mutable buffers concept. See this page for more info on that: http://www.boost.org/doc/libs/1_43_0/doc/html/boost_asio/reference/MutableBufferSequence.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文