从浮点数组创建缓冲区

时间:2018-01-28 22:10:41

标签: c++ boost buffer

我想使用Boost库通过网络发送一系列浮点数。为此,我必须从该数组创建一个缓冲区,但它似乎不起作用。

在这个示例http://www.boost.org/doc/libs/1_66_0/doc/html/boost_asio/tutorial/tutdaytime4/src.html中,它使用了一个字符数组,但我无法使用float数组进行复制。

我尝试使用此构造函数http://www.boost.org/doc/libs/1_66_0/doc/html/boost_asio/reference/buffer/overload6.html,但我无法达到目标。

boost::array<float, 512> arr = { { 0.0f } };
auto buffer = boost::asio::buffer(arr, arr.size());

现在,我想从缓冲区找到0.0f。我试图使用static_cast,但它引发了错误。

1 个答案:

答案 0 :(得分:1)

缓冲区本质上是八位位组序列。

你有一个很大的错误

auto buffer = boost::asio::buffer(arr, arr.size());

因为那里,arr.size()是字节(不是float元素的数量)。修复它的最好方法是让Boost正确计算出尺寸:

auto buffer = boost::asio::buffer(arr); // fixed

现在对于其余部分,从缓冲区读回浮点数没有多大意义(你仍然有数组,所以为什么不使用它呢?)。但是,如果您必须,则可以使用buffer_cast

// extract the first float back - pretend we don't know it's actually the `sending` array
std::cout << "Pi is " << boost::asio::buffer_cast<float const*>(buffer)[0] << "\n";

演示时间

让我们做一个

的演示
  • 将缓冲区写入流
  • 十六进制转储该流(以显示实际的octets0
  • 往返它(回读另一个浮动数组)
  • 验证结果

<强> Live On Coliru

#include <boost/asio.hpp>
#include <boost/array.hpp>
#include <sstream>
#include <iostream>
#include <iomanip>

using Floats = boost::array<float, 10>;

int main() {

    // use a stream to "mock" a communication channel
    std::stringstream ss;

    // fill the stream
    {
        Floats sending = { { M_PI } };
        auto buffer = boost::asio::buffer(sending);
        std::copy(buffers_begin(buffer), buffers_end(buffer), std::ostreambuf_iterator<char>(ss));

        // extract the first float back - pretend we don't know it's actually the `sending` array
        std::cout << "Pi is " << boost::asio::buffer_cast<float const*>(buffer)[0] << "\n";
    }

    // for debug only, print the octects representing the stream contents
    {
        auto n = 0;
        for (uint8_t ch : ss.str()) {
            std::cout << std::hex << "0x" << std::setw(2) << std::setfill('0') << static_cast<int>(ch) << ((n++%4==3)?"\n":" ");
        }
    }

    // now let's roundtrip that float buffer!
    {
        Floats roundtrip = { { M_PI } };
        auto buffer = boost::asio::buffer(roundtrip);
        std::copy(std::istreambuf_iterator<char>(ss), {}, buffers_begin(buffer));

        // now, you can - of course use the buffer_cast again
        std::cout << "Pi is " << boost::asio::buffer_cast<float const*>(buffer)[0] << "\n";

        // but it makes a lot more sense to use the underlying array directly:
        std::cout << "Directly from the roundtripped array: " << roundtrip[0] << "\n";
    }
}

打印

Pi is 3.14159
0xdb 0x0f 0x49 0x40
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
Pi is 3.14159
Directly from the roundtripped array: 3.14159