代码之家  ›  专栏  ›  技术社区  ›  AK_

在C++中寻找内存流

  •  3
  • AK_  · 技术社区  · 14 年前

    在C的奇妙世界里,我可以创建一个不指定大小的内存流, 写入它,然后只获取底层缓冲区。

    如何在C++中做同样的事情?基本上我需要做的是:

    memory_stream  ms(GROW_AS_MUCH_AS_YOU_LIKE);
    
    ms << someLargeObjects << someSmallObjects << someObjectsWhosSizeIDontKnow;
    
    unsigned char* buffer = ms.GetBuffer();
    int bufferSize = ms.GetBufferSize();
    
    rawNetworkSocket.Send(buffer, bufferSize);
    

    顺便说一句,我在我的项目中得到了提升,尽管我并不完全熟悉它。

    谢谢您。

    4 回复  |  直到 14 年前
        1
  •  5
  •   utnapistim    14 年前
    #include <sstream>
    
    std::ostringstream  buffer; // no growth specification necessary
    buffer << "a char buffer" << customObject << someOtherObject;
    
    std::string contents = buffer.str();
    size_t bufferSize = contents.size();
    
    rawNetworkSocket.Send(contents); // you can take the size in Send
    

    使用这种方法,您将不得不解析接收到的结果(因为上面的代码只是将数据转换为非结构化字符串)。

    另一个问题是,因为C++不支持反射,所以必须为对象定义运算符& lt;lt。这是A的代码 Custom 班级:

    template<typename C, typename T>
    std::basic_ostream<C,T>& operator << (
        std::basic_ostream<C,T>& out, const Custom& object)
    {
        out << object.member1 << "," << object.member2 /* ... */ << object.memberN;
        return out;
    }
    

    如果需要结构化序列化,请看一下 boost::serialization .

        2
  •  2
  •   David Rodríguez - dribeas    14 年前

    你可能想看看 std::stringstream 为此目的。这条河将按要求生长。除非您希望将对象保留为二进制而不是ASCII,在这种情况下,您可以查看streambuf对象和实现。

    注意C++没有反射或双/多分派,所以你必须自己为未知大小的对象提供支持:

    class unknown_base {
       virtual void dump( std::ostream & ) const;
    };
    std::ostream& operator<<( std::ostream& o, unknown_base const & obj ) {
       obj.dump( o );
       return o;
    }
    std::string serialize( std::vector<unknown_base*> const & data ) {
       std::ostringstream st;
       for ( std::vector<unknown_base*>::const_iterator it = data.begin(), end = data.end();
             it != end; ++it ) {
          st << **it; // double dereference: iterator, pointer
       }
       return st.str();
    }
    
        3
  •  1
  •   weismat    14 年前

    在增压侧有 Iostreams 这很相似。

        4
  •  0
  •   Matthieu M.    14 年前

    既然你在谈论网络,那么你似乎非常想创建某种信息并通过网络发送它。

    有一些库可以为这些消息创建消息和生成API,其中最著名的是Google协议缓冲区。( protobuf 简而言之)它允许您在短文件(自定义格式)中描述消息的语法,然后自动生成API以在C++/Python /Java中对该消息进行解码。

    优势包括:

    • 互操作性,这也意味着使用脚本语言检查消息的可能性,在调试时很方便。
    • 版本处理(向后和向前兼容),因为我们知道您很快就会修改消息,但可能不会立即升级所有内容。
    • 文本/二进制输出。文本便于调试,每一位计数都需要二进制

    此外,还可以使用文本输出并使用lzo等压缩它以获得一些空间:)