Вызов функции-члена C ++ из Luabind вызывает "Не найдена соответствующая перегрузка" - PullRequest
1 голос
/ 27 апреля 2011

У меня есть некоторые классы, экспортированные в Luabind в DLL, и для этих двух классов все работает нормально (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)

Что может быть причиной этого странного поведения?

1 Ответ

5 голосов
/ 29 апреля 2011

Это копия письма, которое я отправил в список рассылки Luabind. http://sourceforge.net/mailarchive/message.php?msg_id=27420879

Я не уверен, относится ли это и к Windows, и к DLL, но у меня был похожий опыт работы с GCC и общими модулями в Linux: зарегистрированные классы с Luabind, где действует только в этой общей библиотеке, но вызвало ошибки сегментации, если используются за пределами разделяемой библиотеки.

Решение было исправить патч класса luabind :: type_id и сравнить использование typeid (T) .name () вместо typeid (T) :: operator =. Для GCC, причина, по которой оператор typeid может не работать в общих библиотеках объясняется здесь [1]. В этом конкретном случае я загрузил общий библиотека с Lua's require (), которая, к сожалению, не проходит RTLD_GLOBAL, чтобы dlopen.

[1] http://gcc.gnu.org/faq.html#dso

Проблема равенства typeid появилась в других библиотеках C ++, например в boost :: any [2], с тем же исправлением [3], сравнение typeid (T) .name ().

[2] https://svn.boost.org/trac/boost/ticket/754
[3] https://svn.boost.org/trac/boost/changeset/56168

Может быть, прикрепленный патч поможет и в случае с DLL.

--- include.orig/luabind/typeid.hpp
+++ include/luabind/typeid.hpp
@@ -6,6 +6,7 @@
 # define LUABIND_TYPEID_081227_HPP

 # include <boost/operators.hpp>
+# include <cstring>
 # include <typeinfo>
 # include <luabind/detail/primitives.hpp>

@@ -33,17 +34,17 @@

     bool operator!=(type_id const& other) const
     {
-        return *id != *other.id;
+        return std::strcmp(id->name(), other.id->name()) != 0;
     }

     bool operator==(type_id const& other) const
     {
-        return *id == *other.id;
+        return std::strcmp(id->name(), other.id->name()) == 0;
     }

     bool operator<(type_id const& other) const
     {
-        return id->before(*other.id);
+        return std::strcmp(id->name(), other.id->name()) < 0;
     }

     char const* name() const
...