用于“序列化”的reinterpret_cast接收端的数据、字节顺序和对齐方式

发布于 2024-12-29 20:59:04 字数 501 浏览 0 评论 0原文

如果我们有一个 POD 结构说 A,我这样做:

char* ptr = reinterpret_cast<char*>(A);
char buf[20];
for (int i =0;i<20; ++i)
   buf[i] = ptr[i];
network_send(buf,..);

如果接收端远程盒子不一定是相同的硬件或操作系统,我可以安全地执行此操作以“反序列化”:

void onRecieve(..char* buf,..) {
  A* result = reinterpret_cast<A*>(buf); // given same bytes in same order from the sending end

“结果”始终有效吗? C++标准规定POD结构,reinterpret_cast的结果应该指向第一个成员,但这是否意味着即使接收端是不同的平台,实际的字节顺序也将是正确的?

If we have a POD struct say A, and I do this:

char* ptr = reinterpret_cast<char*>(A);
char buf[20];
for (int i =0;i<20; ++i)
   buf[i] = ptr[i];
network_send(buf,..);

If the recieving end remote box, is not necessarily same hardware or OS, can I safely do this to 'unserialize':

void onRecieve(..char* buf,..) {
  A* result = reinterpret_cast<A*>(buf); // given same bytes in same order from the sending end

Will the 'result' always be valid? The C++ standard states with POD structures, the result of reinterpret_cast should point to the first member, but does it mean the actual byte order will be correct also, even if the recieving end is a different platform?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

墨小沫ゞ 2025-01-05 20:59:04

不,你不能。您只能将“向下”转换为 char*,而永远不能返回到对象指针:

  Source                  Destination
     \                         /
      \                       /
       V                     V
 read as char* ---> write as if to char*

代码中:

Foo Source;
Foo Destination;

char buf[sizeof(Foo)];

// Serialize:
char const * ps = reinterpret_cast<char const *>(&Source);
std::copy(ps, ps + sizeof(Foo), buf);

// Deserialize:
char * pd = reinterpret_cast<char *>(&Destination);
std::copy(buf, buf + sizeof(Foo), pd);

简而言之:如果您想要一个对象,则必须< em>有一个对象。如果随机内存位置确实不是对象(即,如果它不是所需类型的实际对象的地址),则不能假装它是对象。

No, you cannot. You can only ever cast "down" to char*, never back to an object pointer:

  Source                  Destination
     \                         /
      \                       /
       V                     V
 read as char* ---> write as if to char*

In code:

Foo Source;
Foo Destination;

char buf[sizeof(Foo)];

// Serialize:
char const * ps = reinterpret_cast<char const *>(&Source);
std::copy(ps, ps + sizeof(Foo), buf);

// Deserialize:
char * pd = reinterpret_cast<char *>(&Destination);
std::copy(buf, buf + sizeof(Foo), pd);

In a nutshell: If you want an object, you have to have an object. You cannot just pretend a random memory location is an object if it really isn't (i.e. if it isn't the address of an actual object of the desired type).

旧话新听 2025-01-05 20:59:04

您可以考虑为此使用模板并让编译器为您处理它

template<typename T>
struct base_type {
    union {
        T    scalar;
        char bytes[sizeof(T)];
    };
    void serialize(T val, byte* dest) {
        scalar = val;
        if is_big_endian { /* swap bytes and write */ }
        else { /* just write */ }
    }
};

You may consider using a templatefor this and letting the compiler handle it for you

template<typename T>
struct base_type {
    union {
        T    scalar;
        char bytes[sizeof(T)];
    };
    void serialize(T val, byte* dest) {
        scalar = val;
        if is_big_endian { /* swap bytes and write */ }
        else { /* just write */ }
    }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文