从浮点数组创建缓冲区

Create a buffer from an array of floating points

本文关键字:创建 缓冲区 数组      更新时间:2023-10-16

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

在这个例子中 http://www.boost.org/doc/libs/1_66_0/doc/html/boost_asio/tutorial/tutdaytime4/src.html 它是用一个字符数组完成的,但我无法使用浮点数组复制。

我尝试使用这个构造函数 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但它抛出了一个错误。

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

你在哪里犯了一个大错误

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";

演示时间

让我们做一个演示

  • 将缓冲区写入流
  • 十六进制转储该流(以显示实际的八位字节0
  • 往返它(读回另一个浮点数组(
  • 验证结果

住在科里鲁

#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