2016-08-04 2 views
2

Это уже давно затирает меня орехами. Я следил за каждым учебным пособием, которое я мог найти в Интернете (вот несколько примеров [[1], [2], возможно, полдюжины хороших, найденных с помощью поиска Google), и до сих пор нет четких объяснений. Хотя кажется, что это должно быть что-то довольно простое, поскольку отсутствие документального объяснения подразумевает, что это то, что большинство людей считают само собой разумеющимся.Как загрузить пользовательский модуль в Lua?

Как загрузить пользовательский модуль в Lua?

По совету вопросов like this one, я написал модуль, который строит общую библиотеку с ожиданием того, что я смог бы загрузить его через require вызова. Однако, когда я делаю это, я получаю неопределенные ошибки символов, несмотря на точные символы, отображаемые в списке из команды nm -g mylib.so.

Эти два учебника, с которыми я связывался, стремятся создать исполняемые файлы, которые выглядят оболочками файла *.lua. То есть, должен быть вызван построенный файл *.exe для запуска программы Lua с помощью настраиваемого модуля.

Я понимаю, что вопросы такого типа задаются здесь довольно часто (как указано в this answer), но я все еще в недоумении. Я попробовал некоторые из пакетов привязки (Luabind и OOLua), но они не сработали отлично (например, мой earlier question - который я в конечном счете выяснил, вроде).

  1. я реализовал класс в C++
  2. Я завернула конструктор, деструкторы и функцию с санками
  3. Я построил его безошибочные-л в общей библиотеке

Еще нет что я получаю undefined symbol: ... ошибки при попытке загрузить его как mod = require('mylib.so'). Как мне это сделать?


Рабочий пример из библиотеки функций

Для записи, просто зарегистрировав основную функцию работает отлично. Ниже код, когда построен как libluatest.so, можно запустить в Lua, используя команды:

> require('libluatest') 
> greet() 
hello world! 

libluatest.cpp

extern "C" 
{ 
    #include <lualib.h> 
    #include <lauxlib.h> 
    #include <lua.h> 
} 

#include <iostream> 

static int greet(lua_State *L) 
{ 
    std::cout << "hello world!" << std::endl; 
    return 0; 
} 

static const luaL_reg funcs[] = 
{ 
    { "greet", greet}, 
    { NULL, NULL } 
}; 


extern "C" int luaopen_libluatest(lua_State* L) 
{ 
    luaL_register(L, "libluatest", funcs); 
    return 0; 
} 

Failing Пример класса

Вот что я застрял в настоящее время. Кажется, он не хочет работать.

myObj.h

#include <string> 
class MyObj 
{ 
    private: 
      std::string name_; 

    public: 
      MyObj(); 
      ~MyObj(); 

      void rename(std::string name); 
}; 

myObj.каст

extern "C" 
{ 
    #include <lualib.h> 
    #include <lauxlib.h> 
    #include <lua.h> 
} 
#include <iostream> 
#include "myObj.h" 

void MyObj::rename(std::string name) 
{ 
    name_ = name; 
    std::cout << "New name: " << name_ << std::endl; 
} 

extern "C" 
{ 
    // Lua "constructor" 
    static int lmyobj_new(lua_State* L) 
    { 
      MyObj ** udata = (MyObj **)lua_newuserdata(L, sizeof(MyObj)); 
      *udata = new MyObj(); 
      luaL_getmetatable(L, "MyObj"); 
      lua_setmetatable(L, -1); 
      return 1; 
    } 

    // Function to check the type of an argument 
    MyObj * lcheck_myobj(lua_State* L, int n) 
    { 
      return *(MyObj**)luaL_checkudata(L, n, "MyObj"); 
    } 

    // Lua "destructor": Free instance for garbage collection 
    static int lmyobj_delete(lua_State* L) 
    { 
      MyObj * obj = lcheck_myobj(L, 1); 
      delete obj; 
      return 0; 
    } 

    static int lrename(lua_State* L) 
    { 
      MyObj * obj = lcheck_myobj(L, 1); 
      std::string new_name = luaL_checkstring(L, 2); 
      obj->rename(new_name); 
      return 0; 
    } 

    int luaopen_libmyObj(lua_State* L) 
    { 
      luaL_Reg funcs[] = 
      { 
        { "new", lmyobj_new }, // Constructor 
        { "__gc", lmyobj_delete }, // Destructor 
        { "rename", lrename }, // Setter function 
        { NULL, NULL } // Terminating flag 
      }; 

      luaL_register(L, "MyObj", funcs); 
     return 0; 
    } 
} 

Составитель в libmyObj.so используя простой CMake строить с C++ 11 стандартных флажками.

Ошибка

> require('libmyObj') 

Ошибка загрузки модуля 'libmyObj' из файла './libmyObj.so': ./libmyObj.so: не определено символ: _ZN5MyObjC1Ev стек отслеживающий: [C]: ? [C]: в функции 'require' stdin: 1: в основном фрагменте [C]:?


Я имею дело с Lua 5.1 на Ubuntu 14.04.

мне интересно, если у него есть что-то делать со смесью C и C++ ...

+0

Спасибо за публикацию чего-то, что работает, можете ли вы опубликовать что-то, что не удается, возможно, тогда мы сможем понять, в чем проблема? – dave

+1

@dave: Готово. Возможно, несвязанный, мне не нравится практика downvoting без комментариев ... никто не выигрывает таким образом – marcman

+0

Не могли бы вы добавить точные ошибки, которые вы получаете, когда компилируете приведенный выше неудачный пример? Какие символы не определены? – harmic

ответ

2
  1. кажется, что вы не реализуете:

    MyObj() ; ~MyObj();

  2. и быть осторожно с функцией luaopen_ *, так как имя модуля - myObj, имя функции должно быть luaopen_libmyObj.

+0

, на # 2, это правильно. Я обобщал свое имя файла, но забыл изменить это имя моего проекта на myObj. Я отредактировал OP, но это хорошая записка, чтобы держать ваш ответ независимо. – marcman

+0

То, что сделал трюк, было просто неудобно. Спасибо. – marcman

Смежные вопросы