如何将自定义模块加载到Lua中?

时间:2016-08-04 05:34:25

标签: c++ lua

这已经让我疯了很久了。我已经按照我在互联网上找到的每个教程(这里有几个例子[[1],[2],通过谷歌搜索找到了大约六个好的教程),但仍然没有明确的解释。虽然看起来它必须是相当简单的,因为缺乏文件化的解释意味着它是大多数人认为理所当然的东西。

如何将自定义模块加载到Lua中?

根据问题like this one的建议,我编写了一个构建共享库的模块,期望我可以通过require调用加载它。但是,当我这样做时,我得到了未定义的符号错误,尽管命令nm -g mylib.so的列表中出现了那些确切的符号。

我之前链接的那两个教程旨在创建查看*.lua文件包装的可执行文件。也就是说,应该调用构建的*.exe文件来运行带有自定义模块的Lua程序。

我知道这些类型的问题在这里经常被问到(如this answer所述),但我仍然感到茫然。我尝试了一些绑定包(Luabind和OOLua),但那些效果不好(例如我的earlier question - 我最终弄明白了,等等。)

  1. 我用C ++实现了一个类
  2. 我用thunks包装了构造函数,析构函数和函数
  3. 我已将其无错误地构建为共享库
  4. 然而,当我尝试将其undefined symbol: ...加载为mod = require('mylib.so')时,无论我遇到什么libluatest.so错误。我该怎么做?

    功能库的工作示例

    对于记录,只需注册基本功能就可以了。以下代码构建为> require('libluatest') > greet() hello world! 时,可以使用以下命令在Lua中运行:

    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;
    }
    

    libluatest.cpp

    #include <string>
    class MyObj
    {
        private:
                std::string name_;
    
        public:
                MyObj();
                ~MyObj();
    
                void rename(std::string name);
    };
    

    类失败示例

    这就是我目前所困扰的。它似乎不想工作。

    myObj.h

    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;
        }
    }
    

    myObj.cpp

    libmyObj.so

    使用带有C ++ 11标准标志的简单CMake构建编译成> require('libmyObj')

    错误

    <div class="form-group has-feedback ng-scope">                      
     <a href="#"  class="btn btn- newbutton7"><strong style="text-align:center;font-size:17px;font-family: sans-serif;margin-left:-4px;">Annual Compensation</strong></a>
     <a href="#"  class="btn btn- newbutton8"><strong style="text-align:center;font-size:17px;font-family: sans-serif;">Monthly Payslips</strong></a>
     <a href="#"  class="btn btn- newbutton9"><strong style="text-align:center;font-size:17px;font-family: sans-serif;margin-left:-8px;">Investment</strong></a>
     </div>
    
      

    从文件'./libmyObj.so'加载模块'libmyObj'时出错:     ./libmyObj.so:undefined symbol:_ZN5MyObjC1Ev stack traceback:[C]:   ? [C]:在函数'require'stdin:1:在主块[C]中:?

    我在Ubuntu 14.04上处理Lua 5.1。

    我想知道它是否与C和C ++的混合有关......

1 个答案:

答案 0 :(得分:2)

  1. 您似乎没有实施:

    MyObj() ; ~MyObj();

  2. 并注意luaopen_ *函数,因为模块名称为myObj,函数名称应为luaopen_libmyObj