【问题标题】:Dynamic (type) binary buffer in C++?C ++中的动态(类型)二进制缓冲区?
【发布时间】:2015-12-10 01:47:34
【问题描述】:

目前,我正在像这样使用std::vector<char>

char data, data2, data3;

vec.push_back(data);
vec.push_back(data2);
vec.push_back(data3);

但是,由于我存储的是二进制数据,有时我需要推送不同大小的数据(即不是单个字符),并且我需要手动将这些数据拆分为单个字节,这既不方便也不可读。

这样的东西会很完美:

buffer.push<int>(some_int); // some_int = 0xAABBCCDD
buffer.push<char>(some_char); // some_char = 0xFF
buffer.push("arbitrary_data", arbitrary_length);

生成的内存将是:

AA BB CC DD FF ...........
// ^ int
//          ^ char

有没有标准的方法,或者我需要库/自己的实现?

【问题讨论】:

  • 虽然这不是最好的方法,但您始终可以使用std::vector&lt;void*&gt;
  • 您可以使用 unsigned char 向量,在需要新项目时调整其大小,然后在数组中构造该类型。
  • 没有标准的方法。 boost::any 对于您正在尝试做的事情很方便。
  • @JamesRoot:除了位置可能未对齐。
  • @AcidShout:你没有。这就是为什么 James 的评论和 KemyLand 的回答是错误的。顺便说一句,不要假设对齐总是到 4 个字节。检查alignof(T)。在相关说明中,也不要假设字节序。推送0xAABBCCDD后很可能会得到0xDD 0xCC 0xBB 0xAA

标签: c++ stl


【解决方案1】:

您要查找的内容称为序列化,它不是 ISO 标准的一部分。不过,Boost 确实有一个库。

【讨论】:

    【解决方案2】:

    这个呢?它甚至适用于非 POD 类型! (注意:C++11 代码!)

    #include <new>
    #include <vector>
    #include <utility>
    
    class BinaryVector : public std::vector<unsigned char> {
        public:
            template<typename T>
            void push(const T &what) {
                this->resize(this->size() + sizeof(T));
                new(this->data() + this->size() - sizeof(T)) T(what);
            }
    
            template<typename T>
            void push(T &&what) {
                this->resize(this->size() + sizeof(T));
                new((T*)(this->data() + this->size() - sizeof(T))) T(XValue(what));
            }
    
            template<typename T>
            T pop() {
                T tmp(std::move(*(T*)(this->data() + this->size() - sizeof(T))));
                ((T*)(this->data() + this->size() - sizeof(T)))->~T();
                this->resize(this->size - sizeof(T));
    
                return tmp;
            }
    };
    

    【讨论】:

    【解决方案3】:

    您可以将指针算法与reinterpret_cast 结合使用,如下例所示:

    std::vector<char> v;
    v.push_back('a');
    v.push_back('b');
    int a = 20;
    v.insert(v.end(), reinterpret_cast<char*>(&a), reinterpret_cast<char*>(&a) + sizeof(a));
    

    或者如果你有一个类/结构:

    struct foo {int a = 1 , b = 2, c = 3;};
    
    std::vector<char> v;
    foo b;
    v.insert(v.end(), reinterpret_cast<char*>(&b), reinterpret_cast<char*>(&b) + sizeof(b));
    

    【讨论】:

      猜你喜欢
      • 2010-12-24
      • 1970-01-01
      • 2010-09-06
      • 1970-01-01
      • 1970-01-01
      • 2014-09-01
      • 2013-03-05
      • 1970-01-01
      • 2020-05-10
      相关资源
      最近更新 更多