6

我目前正在用 C++ 开发一个基于插件的系统,它提供了一个 Lua 脚本接口,我选择使用 luabind。我正在使用 Lua 5 和 luabind 0.9,它们都是静态链接并使用 MSVC++ 8 编译的。当在派生类而不是其父类中定义函数时,我现在无法将函数与 luabind 绑定。

更具体地说,我有一个名为“IPlugin”的抽象基类,所有插件类都从该基类继承。当插件管理器初始化时,它会像这样注册该类及其函数:

luabind::open(L);
luabind::module(L) [
    luabind::class_<IPlugin>("IPlugin")
    .def("start", &IPlugin::start)
];

因为只有在运行时才知道有哪些有效的插件类可用,所以我不得不以一种迂回的方式解决加载插件的问题。插件管理器向 Lua 公开了一个工厂函数,它采用插件类的名称和所需的对象名称。然后,工厂创建对象,将插件的类注册为继承自“IPlugin”基类,并立即在创建的对象上调用一个函数,该对象将自身注册为具有 Lua 状态的全局对象,如下所示:

void PluginExample::registerLuaObject(lua_State *L, string a_name)
{
    luabind::globals(L)[a_name] = (PluginExample*)this;
}

我最初这样做是因为我在 Lua 确定对象的最派生类时遇到了问题,就好像我从插件管理器中注册它一样,它只被称为“IPlugin”的子类型,而不是特定的子类型。我不确定这是否有必要,但它可以工作,随后可以从 Lua 的“a_name”下访问创建的对象。

但是,我遇到的问题是,在派生类中定义的函数根本没有在父类中声明,不能使用。基类中定义的虚函数,例如上面的“start”,可以正常工作,并且在新对象上从 Lua 调用它们会运行“PluginExample”类中各自重新定义的代码。但是,如果我向“PluginExample”添加一个新函数,例如一个不带参数并返回 void 的函数,并像这样注册它:

luabind::module(L) [
luabind::class_<PluginExample, IPlugin>("PluginExample")
    .def(luabind::constructor<PluginManager&>())
    .def("func", &PluginExample::func)
];

在新对象上调用 'func' 会产生以下 Lua 运行时错误:

未找到匹配的重载,候选人:
无效函数(插件示例&)

我正确地使用了 ':' 语法,所以不需要 'self' 参数,而且 Lua 似乎突然无法确定对象的派生类型了。我确定我做错了什么,可能与我的系统架构所需的两步绑定有关,但我不知道在哪里。我非常感谢一些帮助 =)

4

0 回答 0