托卢的联盟类型

时间:2012-02-26 03:18:42

标签: c lua

我认为关于工会的tolua存在一个错误。如果您有这样的声明:

struct SDL_WindowEvent {
    int type;
    int windowID;
};

union SDL_Event {
    int type;
    SDL_WindowEvent window;
};

extern SDL_Event * create(void);
extern void frobnicate(SDL_Event *);

然后应该可以使用这样的lua代码:

event = create()
frobnicate(event)
print(event.window.windowId)
frobnicate(event)

但是对frobnicate(事件)的第二次调用将失败并显示错误:

argument #1 is 'SDL_WindowEvent'; 'SDL_Event' expected.

在调试器上稍微戳了一下,发现event.window访问中的tolua_pushusertype重写了我变量的类型!

这是我到目前为止所尝试的内容:从我的声明中,tolua将创建以下调用以声明SDL_WindowEvent类:

tolua_cclass(tolua_S,"SDL_WindowEvent","SDL_WindowEvent","",NULL);

从而使SDL_Event和SDL_WindowEvent成为两个不相关的类,而不是彼此的基类。假设我后面的代码与以下内容相同:

tolua_pushusertype(tolua_S, event, "SDL_Event");
assert(tolua_isusertype(tolua_S,1,"SDL_Event",0,&tolua_err));
tolua_pushusertype(tolua_S, event->window, "SDL_WindowEvent");
assert(tolua_isusertype(tolua_S,2,"SDL_Event",0,&tolua_err));

然后第四行中的断言将失败,因为自第二行断言以来,堆栈上的值已经神奇地改变了类型。这是因为tolua_pushusertype()更改它 - foo和foo.window具有相同的地址,并且在内部,tolua仅跟踪每个地址的一种类型。如果对象是基类型SDL_Event,则会满足tolua_isusertype(),但这需要上面的tolua_cclass声明将“SDL_Event”作为其第四个参数。当我手动修复它时,两个断言传递,但我不能每次手动更改 - 我想修复tolua这样做,但我不 理解它还是做得那么好。我甚至不知道这是否是正确的做法。

我正在使用tolua 5.1.4,但tolua ++ 1.92.3会出现同样的问题。

首先,我做错了吗?有没有办法可以重写我的声明,以便按照原样使用tolua?或者,如果没有这个,我可以修复一下我的Tolua工具吗?

1 个答案:

答案 0 :(得分:1)

我明白了!解决方案是编辑我的.pkg文件,如下所示:

struct SDL_WindowEvent : SDL_Event {
    int type;
    int windowID;
};

这使得tolua的类层次结构显式化。我太专注于.pkg内容是有效的C代码,看起来似乎。