luabind如何隐式地投射物体?

时间:2014-12-09 19:55:55

标签: c++ casting lua luabind lua-api

如果没有涉及我正在研究的大型多库项目的太多无关细节,我想问一个关于其中发生的特定事件的问题。我正在使用Luabind将我的C ++代码接口与我的Lua代码一起使用,并且我有一个类继承的类结构:

  

GuiWidget

     

GuiButton:GuiWidget

我已经通过Luabind向Lua注册了这两个类。然后我执行以下操作,其中widget是指向GuiWidget类实例的指针:

lua_newtable(luaState);
luabind::object(luaState, widget).push(luaState);
lua_setfield(luaState, 2, "widget");
lua_setglobal(luaState, "event");
//This line connects to some other code I wrote that just executes a file and handles errors.
luaMachine->doFile(widget->getUserString("eventMouseButtonClick"));
lua_pushnil(luaState);
lua_setglobal(luaState, "event");

现在,这个相同的代码片段可以处理从按钮到滚动条甚至整个窗口的任何内容。所以稍后在lua代码中,我会在单击复选框按钮时调用此行代码:

event.widget:setSelected(not event.widget:getSelected())

这很有效。即使推送的指针是GuiWidget指针,lua代码也会知道如何使用GuiButton类对此特定实例唯一的功能。它是如何做到的?如何使用小部件指针并自动知道特定小部件是按钮?我不相信这是可能的,所以我花了一段时间来达到那个解决方案,但我想我会在黑暗中拍摄并且它以某种方式工作。

1 个答案:

答案 0 :(得分:1)

你问了已经有很长时间了,但是我可能对此有一个答案...

  1. luabind在启动可执行文件时为您注册的每种类型生成内部唯一ID(+包装程序等)
  2. LUA_REGISTRYINDEX中有一个名为__luabind_class_id_map的全局“映射”,它将typeid转换为此先前分配的内部唯一ID
  3. 当您返回指针(GuiWidget)时,luabind通过取消引用-> typeid( ptr)来询问返回的指针的typeid。令人惊讶地,这返回的是GuiButton的type_info而不是GuiWidget(尽管GuiWidget ptr = new GuiButton();)
  4. 然后luabind将GuiButton的typeid转换为内部ID,并在另一个LUA_REGISTRYINDEX表(__luabind_class_map)中找到该class_rep。 class_rep包含如何在Lua端存储对象以及与已注册的c ++类有关的其他信息。

最后一个有趣的信息是,Lua端的所有指针都按如下方式存储:dynamic_cast(ptr),以后可以自动将其强制转换为使用先前方法验证的其他类,并使用class_rep中的继承信息

大致就是可以在luabind库中完成隐式转换的方式。