Thrift消息序列化是如何进行的详细分析?

更新于
2026-10-10 05:50:53
1阅读来源:SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计583个文字,预计阅读时间需要3分钟。

Thrift消息序列化是如何进行的详细分析?

序列化浮点型数据流程包括使用 bitwise_cast 和 __int64 将 double 类型的数据转换为无符号整数。以下为简化后的步骤:

Thrift消息序列化是如何进行的详细分析?

1. 使用 bitwise_cast 将 double 类型的数据转换为 unsigned int64。

2.使用 double(from) 函数将转换后的无符号整数转换回 double 类型。

3.Apache Thrift 使用 TBinaryProtocol 进行序列化,具体行号 74。

4.在 Apache Thrift 中,使用 TTransport 类的 writeDouble 方法序列化 double 类型数据,具体行号 171。

序列化浮点型数据流程

bitwise_cast<unsigned __int64,double>(double from) 行 74 C++ apache::thrift::protocol::TBinaryProtocolT<apache::thrift::transport::TTransport>::writeDouble(const double dub) 行 171 C++ apache::thrift::protocol::TVirtualProtocol<apache::thrift::protocol::TBinaryProtocolT<apache::thrift::transport::TTransport>,apache::thrift::protocol::TProtocolDefaults>::writeDouble_virt(const double dub) 行 414 C++ apache::thrift::protocol::TProtocol::writeDouble(const double dub) 行 458 C++ ucrtbased.dll!60dfa298() 未知 [下面的框架可能不正确和/或缺失,没有为 ucrtbased.dll 加载符号] 未知 ucrtbased.dll!60df9fd9() 未知 kernel32.dll!74a86359() 未知 ntdll.dll!76ee8944() 未知 ntdll.dll!76ee8914() 未知

template <class Transport_> uint32_t TBinaryProtocolT<Transport_>::writeDouble(const double dub) { BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t)); BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559); uint64_t bits = bitwise_cast<uint64_t>(dub); bits = htonll(bits); this->trans_->write((uint8_t*)&bits, 8); return 8; }

xfer += oprot->writeFieldBegin("fFhorizontalValue", ::apache::thrift::protocol::T_DOUBLE, 12); xfer += oprot->writeDouble(this->fFhorizontalValue); xfer += oprot->writeFieldEnd();

uint32_t writeDouble(const double dub) { T_VIRTUAL_CALL(); return writeDouble_virt(dub); }

virtual uint32_t writeDouble_virt(const double dub) { return static_cast<Protocol_*>(this)->writeDouble(dub); }


double类型保存成整型

通过联合体将double类型转换成整型

// Use this to get around strict aliasing rules. // For example, uint64_t i = bitwise_cast<uint64_t>(returns_double()); // The most obvious implementation is to just cast a pointer, // but that doesn't work. // For a pretty in-depth explanation of the problem, see // www.cellperformance.com/mike_acton/2006/06/ (...) // understanding_strict_aliasing.html template <typename To, typename From> static inline To bitwise_cast(From from) { BOOST_STATIC_ASSERT(sizeof(From) == sizeof(To)); // BAD!!! These are all broken with -O2. //return *reinterpret_cast<To*>(&from); // BAD!!! //return *static_cast<To*>(static_cast<void*>(&from)); // BAD!!! //return *(To*)(void*)&from; // BAD!!! // Super clean and paritally blessed by section 3.9 of the standard. //unsigned char c[sizeof(from)]; //memcpy(c, &from, sizeof(from)); //To to; //memcpy(&to, c, sizeof(c)); //return to; // Slightly more questionable. // Same code emitted by GCC. //To to; //memcpy(&to, &from, sizeof(from)); //return to; // Technically undefined, but almost universally supported, // and the most efficient implementation. union { From f; To t; } u; u.f = from; return u.t; }



本文共计583个文字,预计阅读时间需要3分钟。

Thrift消息序列化是如何进行的详细分析?

序列化浮点型数据流程包括使用 bitwise_cast 和 __int64 将 double 类型的数据转换为无符号整数。以下为简化后的步骤:

Thrift消息序列化是如何进行的详细分析?

1. 使用 bitwise_cast 将 double 类型的数据转换为 unsigned int64。

2.使用 double(from) 函数将转换后的无符号整数转换回 double 类型。

3.Apache Thrift 使用 TBinaryProtocol 进行序列化,具体行号 74。

4.在 Apache Thrift 中,使用 TTransport 类的 writeDouble 方法序列化 double 类型数据,具体行号 171。

序列化浮点型数据流程

bitwise_cast<unsigned __int64,double>(double from) 行 74 C++ apache::thrift::protocol::TBinaryProtocolT<apache::thrift::transport::TTransport>::writeDouble(const double dub) 行 171 C++ apache::thrift::protocol::TVirtualProtocol<apache::thrift::protocol::TBinaryProtocolT<apache::thrift::transport::TTransport>,apache::thrift::protocol::TProtocolDefaults>::writeDouble_virt(const double dub) 行 414 C++ apache::thrift::protocol::TProtocol::writeDouble(const double dub) 行 458 C++ ucrtbased.dll!60dfa298() 未知 [下面的框架可能不正确和/或缺失,没有为 ucrtbased.dll 加载符号] 未知 ucrtbased.dll!60df9fd9() 未知 kernel32.dll!74a86359() 未知 ntdll.dll!76ee8944() 未知 ntdll.dll!76ee8914() 未知

template <class Transport_> uint32_t TBinaryProtocolT<Transport_>::writeDouble(const double dub) { BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t)); BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559); uint64_t bits = bitwise_cast<uint64_t>(dub); bits = htonll(bits); this->trans_->write((uint8_t*)&bits, 8); return 8; }

xfer += oprot->writeFieldBegin("fFhorizontalValue", ::apache::thrift::protocol::T_DOUBLE, 12); xfer += oprot->writeDouble(this->fFhorizontalValue); xfer += oprot->writeFieldEnd();

uint32_t writeDouble(const double dub) { T_VIRTUAL_CALL(); return writeDouble_virt(dub); }

virtual uint32_t writeDouble_virt(const double dub) { return static_cast<Protocol_*>(this)->writeDouble(dub); }


double类型保存成整型

通过联合体将double类型转换成整型

// Use this to get around strict aliasing rules. // For example, uint64_t i = bitwise_cast<uint64_t>(returns_double()); // The most obvious implementation is to just cast a pointer, // but that doesn't work. // For a pretty in-depth explanation of the problem, see // www.cellperformance.com/mike_acton/2006/06/ (...) // understanding_strict_aliasing.html template <typename To, typename From> static inline To bitwise_cast(From from) { BOOST_STATIC_ASSERT(sizeof(From) == sizeof(To)); // BAD!!! These are all broken with -O2. //return *reinterpret_cast<To*>(&from); // BAD!!! //return *static_cast<To*>(static_cast<void*>(&from)); // BAD!!! //return *(To*)(void*)&from; // BAD!!! // Super clean and paritally blessed by section 3.9 of the standard. //unsigned char c[sizeof(from)]; //memcpy(c, &from, sizeof(from)); //To to; //memcpy(&to, c, sizeof(c)); //return to; // Slightly more questionable. // Same code emitted by GCC. //To to; //memcpy(&to, &from, sizeof(from)); //return to; // Technically undefined, but almost universally supported, // and the most efficient implementation. union { From f; To t; } u; u.f = from; return u.t; }