[英]Can you cast a void pointer to a struct to a specific struct type at runtime?
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.
99%的时间这不是问题,因为我知道用户正在玩什么游戏。 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. 例如,如果我可以向GameState结构添加一个属性,以指示元数据值是KlondikeMetadata类型,并使用该属性将元数据转换为该类型,我想我会很高兴。 Is there a way to do this?
有没有办法做到这一点? Is there a way to specify a type and cast a variable at runtime in C?
有没有一种方法可以在C中运行时指定类型并强制转换变量?
You're going to have to encode it yourself. 您将需要自己对其进行编码。
The easiest solution is to declare an enumeration: 最简单的解决方案是声明枚举:
typedef enum {
GameType_Klondike,
GameType_FreeCell,
} GameType;
then add a field of that type before the pointer: 然后在指针前添加该类型的字段:
GameType game_type;
void *metadata;
Of course, this means you're going to have to set the game_type
field when you initialize metadata
, to remember the type. 当然,这意味着您在初始化
metadata
时必须设置 game_type
字段,以记住类型。
You can also go a bit object-oriented, and have the GameType
be part of the metadata: 您还可以有点面向对象,并将
GameType
包含在元数据中:
struct Metadata {
GameType gametype;
};
struct FreeCellMetadata {
struct Metadata meta;
/* rest of fields here */
};
struct KlondikeMetadata {
struct Metadata meta;
/* rest of fields here */
};
Then you can cast your void *
to struct Metadata *
, and inspect the gametype
field before casting the pointer to the proper type. 然后,您可以将
void *
为struct Metadata *
,并在将指针转换为正确类型之前检查gametype
字段。
For bonus points, use a union: 对于奖励积分,请使用联盟:
struct Metadata {
GameType type;
union {
struct KlondikeMetadata klondike;
struct FreecellMetadata freecellL;
} game;
};
Again, of course this requires you to maintain the data, ie when you initialize a struct KlondikeMetadata
you must remember to set its gametype
field, and so on. 同样,当然,这需要您维护数据,即,在初始化
struct KlondikeMetadata
,必须记住设置其gametype
字段,依此类推。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.