将结构体转换为字节

14

如何在采用小端序处理器的情况下将任何结构体转换为字节数组?


2
请详细说明您的请求 - 请注意,您的答案将极大地依赖于处理器架构。 - KevinDTimm
小端模式的寻址单位是什么?您真正想做什么? - WhirlWind
6个回答

17

在C++中,您可以使用 char* 访问任何类型的对象,因此:

struct S
{
    int a;
    int b;
    // etc.
};

S my_s;

char* my_s_bytes = reinterpret_cast<char*>(&my_s);

// or, if you prefer static_cast:
char* my_s_bytes = static_cast<char*>(static_cast<void*>(&my_s));

在使用reinterpret_caststatic_cast进行类型转换的正确性上,存在至少一些争议。实际上并不重要,因为两者都应该产生相同的结果。


1
太多C++的语言改进了。以前,这个就足够了:char* b = (char*)&my_s;也许如果我再学一次C++,我会先阅读一些关于这些类型转换构造的内容。 - Michael Buen
4
在这种情况下,C风格的强制类型转换与reinterpret_cast相同,因为任何static_castconst_cast的组合都是无效的。使用C++风格的类型转换可以确保您获得所需的类型转换;而C风格的类型转换基本上只是尝试五种不同类型的转换序列,直到找到可行的转换为止。 - James McNellis
答案在您指定的结构体上是正确的。但是,如果添加一些shorts、大整数或字符数据,它就会变得非常错误。 - T.E.D.
@T.E.D.:"非常糟糕"完全取决于char数组的使用方式。当然,有时这不是答案,但通常这已经足够了。要求肯定没有明确说明。 - James McNellis

10

我喜欢使用union

typedef struct b {
  unsigned int x;
  unsigned int y;
} b_s;

typedef union a {
  b_s my_struct;
  char ary[sizeof(b_s)];
} a_u;

3
为什么不直接用ary[sizeof(b)]呢? - Rob Kennedy
1
这就是方法。 - thepenguinmaster
@RobKennedy 看看这个 https://dev59.com/_2445IYBdhLWcg3wl7TW#19577625 ,一切都不晚 :) - anlgrses
谢谢,@Anlgrses,但是我13年前的问题不是“为什么使用联合而不是独立数组?”我的问题是“为什么要使用typedef的sizeof而不是直接使用结构体类型的sizeof?” - Rob Kennedy

10
(char*)&someStruct

3

你想要做什么?如果你想将结构体序列化以便保存到文件或在消息中传递,最好使用专为此设计的工具,例如boost::serialization

如果你只想要一个字节数组,你可以像其他人提到的那样使用reinterpret_cast<char*>,或者执行以下操作:

MyStruct s;
char [] buffer = new char[sizeof(s)];
memcpy(&buffer, &s, sizeof(s));

1

我会窥视 void*

struct gizmo 
{
//w/e
};

//stuff

gizmo *G = new gizmo;

void* bytearray = (void*)G;

你的结构体如何被打包是不确定的,这取决于编译器、ABI和CPU。你需要从手册和一些汇编阅读中弄清楚这一点。


1
你不能通过void*访问字节。 - nos
由于无法取消引用void,因此您无法访问它指向的任何内容(也许可以使用memcpy访问bar,在这种情况下不需要中间的void)。如果foo是void,则foo[0]是编译器错误。请使用unsigned char来访问单个字节。 - nos

0
所有这些答案的问题在于,如果不了解要交换的数据,就无法进行愚蠢的字节交换。字符数据不会被交换。64位整数需要不同类型的交换,具体取决于两个处理器的实现方式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接