在boost Asio bind

时间:2018-01-12 07:16:50

标签: c++11 boost-asio

我问了一个关于boost :: asio here的问题,但今天又提出了一些问题。我有一些非常简单的服务器客户端结构,并且在某一点上有async_write命令:

ushort _nSetupReceiveBuffer[_nDynamicSize];
boost::asio::async_write(m_oSocket, boost::asio::buffer(&_nSetupReceiveBuffer, _nDynamicSize),
    [this, self](boost::system::error_code _oError, std::size_t)
    {
        std::cout << _nSetupReceiveBuffer.size() << std::endl;
    });

不幸的是,它会导致error: ‘_nSetupReceiveBuffer’ is not captured错误。 所以我的问题是:

  1. 如何捕获nSetupReceiveBuffer或更好地捕获其引用? (使用[this, self, &_nSetupReceiveBuffer]构建捕获其引用但在收到任何数据之前导致分段错误(核心转储)错误,因为,我认为,它作为回调执行,原始变量已被删除。)

  2. 我使用ushort是因为我希望使用cv::Mat设置传输CV_16U张图片,并试图遵循this的想法。你有其他想法如何通过boost传输cv :: Mat文件?我只能使用无损容器,但我想避免高CPU负载。在我的情况下,带宽应该不是问题。然而,这只是事实的一半,我尝试使用序列化器将图像序列化为一个字符串,工作正常,但显着增加了大小: - (

  3. 为了避免问题1.我可以使_nSetupReceiveBuffer成为一个成员变量,但我需要在运行时动态分配它,我不知道怎么做?第二个缺点是,变量类型ushort是固定的,但我想要灵活,例如如果我有另一个CV_8U类型的视频流,我需要将其更改为uchar
  4. 我的最后一种方法是reshape() cv::Mat并使用std::vector<ushort>作为成员varbel来存储单个值。这是合理的还是仅产生大量开销?我可以在没有指定类型的情况下将矢量定义为成员变量,还是应该为每种类型定义一个,然后只使用适当的一个?
  5. 感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

  1.   

    如何捕获nSetupReceiveBuffer或更好地捕获其引用? (使用[this,self,&amp; _nSetupReceiveBuffer]构建它的引用但是甚至在收到任何数据之前都会导致分段错误(核心转储)错误,因为,我认为它是作为回调执行的,原始变量已被删除。)

  2. 捕获将消失的变量的引用是无用的。

    捕获变量意味着您无法将其传递给异步调用。

    1.   

      为了避免问题1.我可以使_nSetupReceiveBuffer成为一个成员变量,但我需要在运行时动态分配它,我不知道怎么做?

    2. 使用std::vector。这应该是C ++中的第1课。

      >And a second drawback would be, that the variable type ushort is fixed, but I want to be flexible, e.g. if I have another video stream of CV_8U type, I need to change it to uchar.
      

      这表明您应该将IO操作与您的类分开。如果您创建一个表示IO操作的类型,则可以使缓冲区成为该类型的成员。

      1. 我的最后一种方法是重塑()cv :: Mat并使用std :: vector作为存储单个值的成员variabel。这是合理的还是仅产生大量开销?我可以在没有指定类型的情况下将矢量定义为成员变量,还是应该为每种类型定义一个,然后只使用适当的一个?
      2. 我建议将序列化问题分开,并使用Boost Serialization,例如这里给出:Serializing OpenCV Mat_<Vec3f>

        如果您可以确定矩阵始终是连续的,则可以直接使用缓冲区:

        boost::asio::async_write(m_oSocket, boost::asio::buffer(mat.ptr(), mat.total()),
            [this, self](boost::system::error_code ec, std::size_t tranferred)
            {
                std::cout << tranferred << std::endl;
            });
        

        当然,您将拥有与上述nSetupReceiveBuffer相同的相同的生命周期注意事项。另外,请记住,在IO操作完成之前,其他线程不应触摸数据。