Вызов функции-члена C из Luabind вызывает «Перегрузка соответствия не найдена»

#c #lua #luabind

#c #lua #luabind

Вопрос:

У меня есть несколько классов, экспортированных в Luabind в DLL, и все работает нормально для этих двух классов (LuaScriptManager, EventManager). Я могу вызывать их функции из Lua, и все хорошо, но сейчас я пытаюсь настроить какой-то новый класс в моем клиентском исполняемом файле, который связывается с DLL, и пока что совсем безуспешно.

Вот сообщение об ошибке, которое я получаю для каждой функции, которую я вызываю: «Перегрузка соответствия не найдена, кандидаты: void LoadResource(ResourceManageramp;, std::string constamp;)»

Привязка к классу выполняется из http://www.nuclex.org/articles/5-cxx/1-quick-introduction-to-luabind:

 struct Manager {
Manager() :
m_ResourceCount(0) {}

void loadResource(const std::string amp;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", amp;Manager::loadResource)
    .property("ResourceCount", amp;Manager::getResourceCount)
    ];

    luabind::globals(l)["MyResourceManager"] = amp;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. Хорошо, я сузил область поиска до: если состояние lua открыто в DLL = не работает, если состояние lua открыто в клиентском exe = работает. Но, конечно, я хотел бы иметь одинаковое состояние в обоих, чтобы я мог совместно использовать объекты между ними….

2. Может ли это быть проблемой с искажением имени?

Ответ №1:

Это копия письма, которое я отправил в список рассылки 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]. В данном конкретном случае я загрузил разделяемую библиотеку с помощью функции require() Lua, которая, к сожалению, не передает 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 constamp; other) const
     {
-        return *id != *other.id;
         return std::strcmp(id->name(), other.id->name()) != 0;
     }

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

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

     char const* name() const