呼叫 C++ Luabind 的成员函数导致“未找到匹配的重载”
我已经将一些类导出到 DLL 中的 Luabind,并且这两个类(LuaScriptManager、EventManager)一切正常。 我可以从 Lua 调用它们的函数,一切都很好,但现在我试图在我的客户端可执行文件中设置一些与 DLL 链接的新类,但到目前为止一点运气都没有。
这是我调用的每个函数收到的错误消息: “找不到匹配的重载,候选人:void loadResource(ResourceManager&, std::string const&)”
类绑定来自 http://www.nuclex.org/articles/5-cxx/1-quick-introduction-to-luabind:
struct Manager {
Manager() :
m_ResourceCount(0) {}
void loadResource(const std::string &sFilename) {
++m_ResourceCount;
}
size_t getResourceCount() const {
return m_ResourceCount;
}
size_t m_ResourceCount;
};
static Manager MyResourceManager;
void Bind(lua_State* l)
{
// Export our class with LuaBind
luabind::module(l) [
luabind::class_<Manager>("ResourceManager")
.def("loadResource", &Manager::loadResource)
.property("ResourceCount", &Manager::getResourceCount)
];
luabind::globals(l)["MyResourceManager"] = &MyResourceManager;
}
这是相应的 lua 测试代码:
-- The following call will fail with the above error
MyResourceManager:loadResource("abc.res")
--MyResourceManager:loadResource("xyz.res")
-- If the function is commented out, this will work (accessing the property)
ResourceCount = MyResourceManager.ResourceCount
-- Calling my other classes' functions work fine
LuaScriptManager.GetInstance():WriteLine(ResourceCount)
这种奇怪行为的原因可能是什么?
I've got some classes exported to Luabind in a DLL, and everything is working fine for those 2 classes (LuaScriptManager, EventManager).
I can call their functions from Lua and all is well, but now I'm trying to setup some new class in my client executable which links with the DLL and so far no luck at all.
Here's the error message I get for every function that I call:
"No matching overload found, candidates: void loadResource(ResourceManager&, std::string const&)"
The class binding is from http://www.nuclex.org/articles/5-cxx/1-quick-introduction-to-luabind:
struct Manager {
Manager() :
m_ResourceCount(0) {}
void loadResource(const std::string &sFilename) {
++m_ResourceCount;
}
size_t getResourceCount() const {
return m_ResourceCount;
}
size_t m_ResourceCount;
};
static Manager MyResourceManager;
void Bind(lua_State* l)
{
// Export our class with LuaBind
luabind::module(l) [
luabind::class_<Manager>("ResourceManager")
.def("loadResource", &Manager::loadResource)
.property("ResourceCount", &Manager::getResourceCount)
];
luabind::globals(l)["MyResourceManager"] = &MyResourceManager;
}
And here's the corresponding lua test code:
-- The following call will fail with the above error
MyResourceManager:loadResource("abc.res")
--MyResourceManager:loadResource("xyz.res")
-- If the function is commented out, this will work (accessing the property)
ResourceCount = MyResourceManager.ResourceCount
-- Calling my other classes' functions work fine
LuaScriptManager.GetInstance():WriteLine(ResourceCount)
What could be the cause of this strange behavior ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是我发送到 Luabind 邮件列表的邮件的副本。
http://sourceforge.net/mailarchive/message.php?msg_id=27420879
我不确定这是否也适用于 Windows 和 DLL,但我有类似的
Linux 上的 GCC 和共享模块的经验:注册类
与 Luabind 仅在该共享库中有效,但导致
如果跨共享库边界使用,则会出现分段错误。
解决方案是修补 luabind::type_id 类,然后比较
使用 typeid(T).name() 而不是 typeid(T)::operator= 。对于海湾合作委员会来说,
typeid 运算符可能无法跨共享库工作的原因
在此进行了解释[1]。在这种特殊情况下,我加载了共享
带有 Lua 的 require() 的库,不幸的是,它没有通过
RTLD_GLOBAL 到 dlopen。
typeid 相等问题也出现在其他 C++ 库中,例如
在 boost::any [2] 中,具有相同的修复 [3],typeid(T).name() 比较。
也许附加的补丁对于 DLL 也有帮助。
This is a copy of a mail I sent to the Luabind mailing list.
http://sourceforge.net/mailarchive/message.php?msg_id=27420879
I am not sure if this applies to Windows and DLLs, too, but I had a similar
experience with GCC and shared modules on Linux: classes registered
with Luabind where only valid within that shared library, but caused
segmentation faults if used across shared library boundaries.
The solution was to patch the luabind::type_id class, and compare
using typeid(T).name() instead of typeid(T)::operator=. For GCC, the
reason why the typeid operator might not work across shared libraries
is explained here [1]. In this particular case, I loaded the shared
library with Lua's require(), which, unfortunately, does not pass
RTLD_GLOBAL to dlopen.
The typeid equality problem has appeared in other C++ libraries, e.g.
in boost::any [2], with the same fix [3], typeid(T).name() comparison.
Maybe the attached patch helps in the case of DLLs, too.