将字符指针(char*)转换为结构体

7

我有一个结构体:

//Custom packet structure.
struct UserPacket
{
 __int64 pingTime;
} CustomPacket;

我已经知道如何将它转换为char*。现在我想将char*转换回结构体。有什么建议吗?


1
你如何将其转换回去完全取决于你进行正向转换的方式。请发布正向转换的详细信息。 - CB Bailey
看起来你正在尝试序列化数据。在这里要非常小心填充和对齐问题(虽然你的单成员示例应该没问题)。你是将char*写入文件或其他离开进程的流吗?还可能需要考虑字节顺序等其他问题。 - philsquared
如果这些数据要在不同的计算机之间传输,请注意字节序。 - Potatoswatter
2个回答

12

如果是C++:

char* theCharPtr; // has your converted data

UserPacket* fromChar = reinterpret_cast<UserPacket*>(theCharPtr);

5
由于这个帖子是一个重要的搜索结果,需要注意从[[un]signed] char *转换为SomethingElse *在标准中并不被官方认可。严格的别名规则只允许SomethingElse *转换为char *。当然,大多数实现确实允许这样做,并且会做大多数人所期望的事情,顺便说一句,我有时也会利用这一点,但始终要明确警告它并不能保证行为一致。特别是在某些实现中,可能会导致结果SomethingElse包含一个基本类型成员,现在错位了,从而使程序在运行时崩溃。 - underscore_d
@underscore_d 这也适用于C标准吗?即从char*转换为SomethingElse*的强制转换? - Nubcake
@Nubcake 是的。然而,在C中,您可以使用union来避免这种情况,但在C++中,您不能。请参见:将char数组强制转换为struct类型 虽然如此,从C++20左右(文件正在准备中),终于允许通过reinterpret_cast从原始字节的内存中“创建”一个合适的仅数据对象。目前我们必须使用memcpy()或类似方法来解决现有标准语言的问题。 - underscore_d
1
@underscore_d 我的印象是 char、unsigned char 和 std::byte 类型是明确允许的,但 signed char 不被允许。 - Lambo
1
@Lambo 对的!C11表示signed char是可以的。但是cppref只提到了unsigned char,未经修饰的charstd::byte标准对于unsigned char或未经修饰的char有许多允许,包括7.11.11:“试图通过其类型与以下类型之一不相似的glvalue访问对象的存储值[意味着]行为是未定义的”。其他只允许unsigned charbyte - underscore_d

5

将其强制类型转换。以下是一些示例(其中两个使用类型转换)。

CustomPacket  customPacket;

char *          p = (char *) &customPacket;

CustomPacket *  pPacket    = (CustomPacket *) p;
CustomPacket *  pAlternate = &customPacket;

希望这能帮到您。

2
在C++中应避免使用C风格的转换,因为编译器会尝试每一种转换,直到找到“可以”的那个。像@Zoltan这样使用它,这样你就可以清楚地看到作者在做什么以及他的想法是什么。 - jaor
@jaor - 太有趣了!我之前不知道C++还有这个特性。每天都在学到新东西。 :) - Sparky

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