2

I have a struct defined like this:

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

    void *metadata;
};
typedef struct GameState GameState;

The metadata pointer will point to another struct of a type decided at runtime. For example it might be:

struct KlondikeMetadata{
    bool draw3;
    int drawcount;
};
typedef struct KlondikeMetadata KlondikeMetadata;

Or maybe:

struct FreeCellMetadata{
    int reserveCells;
};
typedef struct FreeCellMetadata FreeCellMetadata;

The actual metadata struct used depends on the game the user is playing. 99% of the time this isn't a problem because I know what game the user is playing. However, there are cases where I don't (and can't) know this.

My question is, is there a way to determine or specify the correct metadata type at runtime?

For example if I could add a property to the GameState struct indicating that the metadata value is of type KlondikeMetadata and use that to cast the metadata to that type, I think I'd be golden. Is there a way to do this? Is there a way to specify a type and cast a variable at runtime in C?

4

1 回答 1

7

您将不得不自己对其进行编码。

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

typedef enum {
 GameType_Klondike,
 GameType_FreeCell,
} GameType;

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

GameType game_type;
void     *metadata;

当然,这意味着您必须在初始化时设置字段,以记住类型。game_typemetadata

您还可以稍微面向对象,并GameType成为元数据的一部分:

struct Metadata {
 GameType gametype;
};

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

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

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

对于奖励积分,请使用工会:

struct Metadata {
 GameType type;
 union {
 struct KlondikeMetadata klondike;
 struct FreecellMetadata freecellL;
 } game;
};

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

于 2013-03-19T14:01:04.737 回答