您可以在运行时将结构的void指针强制转换为特定的结构类型吗?

Dou*_*hes 2 c struct pointers void

我有一个像这样定义的结构:

struct GameState {
    int score;
    int moves;
    bool won;

    void *metadata;
};
typedef struct GameState GameState;
Run Code Online (Sandbox Code Playgroud)

元数据指针将指向在运行时决定的另一个类型的结构.例如,它可能是:

struct KlondikeMetadata{
    bool draw3;
    int drawcount;
};
typedef struct KlondikeMetadata KlondikeMetadata;
Run Code Online (Sandbox Code Playgroud)

或者可能:

struct FreeCellMetadata{
    int reserveCells;
};
typedef struct FreeCellMetadata FreeCellMetadata;
Run Code Online (Sandbox Code Playgroud)

使用的实际元数据结构取决于用户正在玩的游戏.99%的时间这不是问题,因为我知道用户正在玩什么游戏.但是,有些情况下我不会(也不可能)知道这一点.

我的问题是,有没有办法在运行时确定或指定正确的元数据类型?

例如,如果我可以向GameState结构添加一个属性,指示元数据值是KlondikeMetadata类型并使用它来将元数据转换为该类型,我想我会是金色的.有没有办法做到这一点?有没有办法在C中指定一个类型并在运行时强制转换变量?

unw*_*ind 7

你将不得不自己编码.

最简单的解决方案是声明枚举:

typedef enum {
 GameType_Klondike,
 GameType_FreeCell,
} GameType;
Run Code Online (Sandbox Code Playgroud)

然后在指针前添加该类型的字段:

GameType game_type;
void     *metadata;
Run Code Online (Sandbox Code Playgroud)

当然,这意味着你将不得不设置game_type现场,当你初始化metadata,要记住的类型.

你也可以去面向对象,并GameType成为元数据的一部分:

struct Metadata {
 GameType gametype;
};

struct FreeCellMetadata {
 struct Metadata meta;
 /* rest of fields here */
};

struct KlondikeMetadata {
 struct Metadata meta;
 /* rest of fields here */
};
Run Code Online (Sandbox Code Playgroud)

然后你可以转换void *struct Metadata *,并gametype在将指针转换为正确的类型之前检查字段.

对于奖励积分,请使用联盟:

struct Metadata {
 GameType type;
 union {
 struct KlondikeMetadata klondike;
 struct FreecellMetadata freecellL;
 } game;
};
Run Code Online (Sandbox Code Playgroud)

同样,当然这需要您维护数据,即初始化时struct KlondikeMetadata必须记住设置其gametype字段,依此类推.