这个问题类似于
serialize any data type as vector<uint8_t> - use reinterpret_cast?
template <typename T>
inline void pack (std::vector< uint8_t >& dst, T& data) {
uint8_t * src = static_cast < uint8_t* >(static_cast < void * >(&data));
dst.insert (dst.end (), src, src + sizeof (T));
}
解压缩
template <typename T>
inline void unpack (vector <uint8_t >& src, int index, T& data) {
copy (&src[index], &src[index + sizeof (T)], &data);
}
我正在尝试将任何类型的数据打包成字节数组。
问题1:我使用uint8_t *进行繁琐的实现,我希望选择矢量是最好的。
问题2:我无法使用上述函数正确打包std :: string。请告诉我上述函数在打包所有类型的数据类型时的舒适度
请告诉我如何将std :: string合并到上面的soluntion i e pack和std :: string into vector
我想打包的数据类型:
所有POD 的std :: string 矢量本身..
外部问题:
我想将这些类打包成一个字节数组
class StartPeerSessionRequest : public Request {
public:
StartPeerSessionRequest();
virtual ~StartPeerSessionRequest();
void composeRequestwithHardCodeValues();
vector<uint8_t> packRequestWithTemplate();
private:
uint16_t mProtocolVersion;
uint16_t mSessionFlags;
uint16_t mMaxResponseLength;
string mMake;
string mModel;
string mSerialNumber;
uint8_t mTrackDelay;
string mHeadUnitModel;
string mCarModelYear;
string mVin;
uint16_t mVehicleMileage;
uint8_t mShoutFormat;
uint8_t mNotificationInterval;
};
class Message {
public:
Message();
virtual ~Message();
void composeMessage(vector<uint8_t> data, uint16_t opcode, uint16_t lengthOfData);
uint16_t packetheader;
uint16_t length;
uint16_t request_response_id;
uint16_t opcode;
uint16_t checksum;
vector<uint8_t> data;
}
我选择的字节数组数据类型是vector(uint8_t)
我想将其写入设备文件或通过蓝牙网络发送。我不想反序列化同一个类。我将收到一个响应,它又是一个字节数组,我需要最终将响应解包到另一个类
答案 0 :(得分:4)
tl; dr:使用Boost.Serialization或Protocol Buffers等序列化库。
广告1)矢量没问题。 编辑:但流会更好。
Ad 2)好吧,你不能用这种方式序列化间接对象,因为你只能获得指向实际数据的指针,而不是数据本身。而且您只能序列化plain old data(standard layout in C++11)个对象;或者更确切地说,不保证反序列化非普通旧数据/标准布局的对象将导致工作对象。 std::string
(也没有任何其他容器)不是POD并且包含间接(std::string
只是一种特殊的向量)。
无法将任意非标准布局对象序列化/打包到字节数组而无需特殊支持。您必须为每个这样的类型编写序列化和反序列化函数,或者您必须放弃字节数组要求并使用boost::any之类的东西来维护类型信息并在幕后为您正确调用构造函数和析构函数。请注意,boost::any
本身是一个具有间接的非标准布局对象。
广告修改
我不想反序列化同一个类。
是的,你这样做。在连接的另一端。所以要么
有数千种方法可以序列化每种类型。字符串可以序列化为长度,内容或内容以指定的终结符(通常为0字节)终止,整数(字符串大小为整数)可以序列化为不同的固定字节数,按不同的顺序(字节序),使用变量长度编码等。
然后有变化。我看到你确实包含了协议版本。但是你还必须根据版本编写反序列化代码以执行不同的操作,这通常意味着无论如何都要逐个成员地执行(您希望在版本上独立输出相同的结构以保持下游代码正常)等。 / p>
如果您没有决定协议,我建议您查看Boost.Serialization和Protocol Buffers个库。
如果出于某种原因你不能使用它们(除非目标受到极大的限制,你应该能够;我使用的是同时使用Boost和Protobuf并在所有当前主要移动平台上运行的移动应用程序),至少阅读他们的技术说明,可能会查看代码,以便您知道如何很好地进行序列化。