具有柔性构件类型的结构?

时间:2014-02-11 19:27:16

标签: c struct sdl

我正在开发一款小游戏,我有一个包含精灵信息的结构。该sprite的成员之一可以是SDL_Texture,也可以是任何其他类型。我正在编写这个结构作为支持多个平台的方法。我的整个代码引用了这个结构,并且根据它运行的平台,“texture”成员可以是任何类型:SDL_Texture,kgl_Tex,byte []等。

如何创建具有灵活成员类型的结构并允许我的代码支持多种特定于平台的类型?顺便说一下,我在使用ANSI C。

这是我正在寻找的更“真实”的例子:

typedef struct
{
    int frames;
    int x;
    int y;
    ? *texture;
} Sprite;

void load_sprite()
{
    Sprite sprite;

    sprite.texture = load_sdl_sprite('test.png'); // This will return a SDL_Texture*
    sprite.texture = load_kgl_sprite('test.png'); // This will return a kgl_tex*
    sprite.texture = load_lib_sprite('test.png'); // This will return a sprite_t*
}

4 个答案:

答案 0 :(得分:3)

如果它只是一个值,那基本上是“指针”,我可能会通过别名指针解决它,每个平台使用不同的别名:

#if defined WITH_SDL
 #include SDL-specific headers
 typedef SDL_Surface Texture;
#elif defined WITH_KGL
 #include KGL-specific headers
 typedef kgl_tex Texture;
#elif defined WITH_LIB
 #include LIB-specific headers
 typedef sprite_t Texture;
#else
 #error Undefined platform, no Texture representation.
#endif

typedef struct
{
    int frames;
    int x;
    int y;
    Texture *texture;
} Sprite;

这有(史诗般的)赢得了保持平台首选的原生类型。它还避免在不为其构建时提及其他平台的类型,这可能是一个巨大的胜利。

typedef图层可能会在分配时发出警告类型SDL_Surface *的值为Texture *的指针。如果发生这种情况,那么仅仅typedef void Texture就可以了,并且完成它。

您应该将上述内容放在某些特定于应用程序的标头(sprite.h)或其他内容中,然后将#include放在需要创建Texture的所有文件中。你的示例代码不太可信;你永远不会有三次调用不同的API,它们会像往常一样完成相同的事情。通常,您使用上面的预处理器符号,或者例如sprite-sdl.csprite-kgl.c等等。它是在那些实现上述Sprite所需的#include功能的文件中。

我添加了特定于API的包含作为占位符,这是一种方法。

答案 1 :(得分:1)

在您的结构中将变体类型创建为void*,并根据您的平台跟踪实际类型。

然后根据需要在每个平台上创建访问函数,将指针转换为需要的类型。

typedef struct
{
    int frames;
    int x;
    int y;
    void* texture;
} Sprite;


void load_sprite()
{
    Sprite sprite;

    sprite.texture = load_sdl_sprite('test.png'); // This will return a SDL_Texture*
    sprite.texture = load_kgl_sprite('test.png'); // This will return a kgl_tex*
    sprite.texture = load_lib_sprite('test.png'); // This will return a sprite_t*
}

因为纹理是void*类型,您可以为其指定任何您喜欢的指针类型。由你来跟踪它实际指向的内容。

或者使用大量#ifdef语句来阻止基于平台的实际类型。

答案 2 :(得分:0)

可能是你有一个void指针字段,它保存了实际纹理数据/结构的地址; 另一个int字段,其中包含一个“类型”代码,表示纹理的类型。

答案 3 :(得分:0)

另一种保留所有可能性的方法(但保留它是一个错误的想法)是建立一个带有类型和联合的结构:

enum Texture_type
{
    type_sdl,
    type_kgl,
    type_sprite_t
};

struct Texture
{
   enum Texture_type type;
   union all
   {
       SDL_Surface* Tsdl;          
       kgl_Tex* Tkgl;
       sprite_t* Tspr;
   }
}

结构纹理可以保存任何纹理。 分配它:你填写类型,然后将好指针填入联合。 删除它:您打开类型以调用SDL_FreeSurface或其他