繁体   English   中英

将void *转换为具有数组成员的结构

[英]cast void* to a struct with an array member

我正在尝试将数据流直接转换为一个结构,该结构实际​​上具有可变数量的其他结构作为成员。 这是一个例子:

    struct player
    {
        double lastTimePlayed;
        double timeJoined;
    };

    struct team
    {
        uint32_t numberOfPlayers;
        player everyone[];
    };

然后我打电话给:

    team *myTeam = (cache_team*)get_stream();

这应该像某种序列化一样工作,我知道我的流的结构完全如上所述,但是我有numberOfPlayers是变量的问题。

我的流从代表团队球员数量的4个字节开始,然后包含每个球员(在这种情况下,每个球员只有lastTimePlayed和timeJoined)。

发布的代码似乎正在运行,由于默认的赋值和复制构造函数,我仍然从编译器收到警告,但是我的问题是,可以通过其他方式(一种更好的方式)来执行此操作。

顺便说一句,我的流实际上是到文件的直接映射,我的目标是使用该结构,就好像它是文件本身一样(该部分正常工作)。

uint32_t是4个字节。 如果以8个字节开头,则需要uint64_t

如果要消除警告,可以将默认的副本和分配设为私有:

struct team {
    // ...
private:
    team(const team &);
    team &operator=(const team &);
};

由于您可能无论如何都要通过指针传递所有内容,因此可以防止意外复制。

将映射的指针转换为该结构可能是最简单的方法。 重要的是确保所有内容正确排列。

Visual Studio 2012提供了以下内容:

warning C4200: nonstandard extension used : zero-sized array in struct/union
A structure or union contains an array with zero size.
Level-2 warning when compiling a C++ file and a Level-4 warning when compiling a C file.

这似乎是合法信息。 我建议您将结构修改为:

struct team
{
        uint32_t numberOfPlayers;
        player everyone[1];
};

这样的定义不太优雅,但是结果将基本相同。 C ++不检查索引的值。 大量的代码正在使用它。

新的开发应尽可能避免“违反数组大小”。 以这种方式描述外部结构是可以接受的。

Scaryrawr的解决方案和您的解决方案都可以解决,但实际上我正在寻找另一种方法。

我实际上确实找到了。 我使用了uint32_t everyPtr而不是数组,然后将使用reinterpret_cast将uint32_t转换为指针,如下所示:

player *entries = reinterpret_cast<player*>(&team->everyonePtr);

那么我的映射就会按预期工作,并且我认为它比array [1]甚至是空的更容易理解。 感谢大伙们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM