【问题标题】:struct to bytes结构到字节
【发布时间】:2010-04-24 23:13:23
【问题描述】:

我正在尝试使用 fread() 从文件中读取加密的结构数据。一旦我得到解密的结构字节,我想把它们放回这个结构中。

struct data
{
  std::string s1;
  std::string s2;
  std::string s3;
  LONG l;
};

如何将结构转换为可以从字节重构的字节?

【问题讨论】:

  • 是字符串std::string吗?如果不是,那是什么?
  • 戴夫,这令人困惑。你是说结构内的标识符'string'实际上是char *的typedef?这就是尼尔要问的。
  • 一个问题是 LONG 数据类型没有很好地定义......在一台计算机上它可能是 32 位,而在另一台计算机上它可能是 64 位。除非数据永远不会离开单台计算机,否则最好使用 int32_t 或其他具有明确定义位宽的类型。

标签: c++ serialization


【解决方案1】:

问题是std::string 不包含有问题的字节,它包含一个指向您实际要存储的字节的指针。您可能应该将每个字符串保存为空终止字符串,然后在文件中保存很长时间之后的原始字符串。

如果您正在寻找类似 .NET 提供的“点击式”序列化解决方案,您将无法在 C++ 中找到所需的内容。 Boost's serialization library 可能会有所帮助,因为它会为您序列化一些标准库对象,但您需要自己实现这样的用户定义类。

【讨论】:

    【解决方案2】:

    我会这样做:

    struct serialized_data {
      size_t s1_offset;
      size_t s2_offset;
      size_t s3_offset;
      long l;
      char strings[1];
    };
    
    serialized_data* serialize (data d) {
        serialized_data* s = malloc(sizeof(serialized_data) + d.s1.length() + d.s2.length() + d.s3.length() + 3);
        s->s1_offset = 0;
        s->s2_offset = d.s1.length() + 1;
        s->s3_offset = s2_offset + d.s2.length() + 1;
        s->l = d.l;
        strcpy(s->strings, d.s1.c_str());
        strcpy(s->strings + s->s2_offset, d.s2.c_str());
        strcpy(s->strings + s->s3_offset, d.s3.c_str());
    
        return s;
    }
    

    【讨论】:

    • 记得处理有人在你的反序列化代码中传入垃圾偏移量/长度的情况。
    【解决方案3】:

    对于一般情况,编写一个函数来手动序列化结构中的所有成员,另一个通过按顺序反序列化所有成员来从字节流创建结构。您可以使用脚本为您生成这些函数(遗憾的是,C++ 不支持 Java 反射之类的东西)。

    你可以看看boost/serialization

    【讨论】:

    • 对于一个结构来说,这就是在轮子上打破蝴蝶,但我认为它也不值得一票否决,因为他写了“for the general case”。
    【解决方案4】:
    struct data 
    { 
      std::string s1; 
      std::string s2; 
      std::string s3; 
      long l; 
    };
    
    
    int Write(FILE* file, const data* myData)
    {
       unsigned long length;
    
       length = myData->s1.size();
       fwrite((void*) &length, sizeof(length), 1, file);
       fwrite((void*) myData->s1.data(), length, 1, file);
       ... // write the other strings and long here
    }
    
    int Read(FILE* file, data* myData)
    {
       unsigned long length;
       char* buffer;
    
       fread((void*) &length, sizeof(length), 1, file);
       buffer = new char[length];
       length = fread(&buffer, length, 1, file);
       myData.s1 = string(buffer, length);
    }
    

    当然,做错误检查等等

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-24
      • 2011-06-30
      • 1970-01-01
      • 2016-12-09
      • 2011-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多