代码之家  ›  专栏  ›  技术社区  ›  Karl Chris Geirman

在C++和Lua之间来回发送变量指针?

  •  1
  • Karl Chris Geirman  · 技术社区  · 15 年前

    我在寻找一种在C++和Lua之间来回传送变量地址的方法。例如,将对象从C++传输到Lua,并进行一些处理,然后将其传递回C++。

    但是,如何从Lua中执行C++函数或方法呢?或者是否需要解决方法?

    如果可能的话,你能提供一个代码片段来告诉我是怎么做的吗?

    我知道我还没有完全了解整个情况,所以如果有什么不对劲,请纠正我。

    3 回复  |  直到 15 年前
        1
  •  10
  •   Community CDub    5 年前

    我花了很多时间来让Lua在C++课程中工作得很好。Lua比C++更像是一种C风格的API,但是有很多方法可以与C++一起使用。

    light userdata

    class person
    {
      private:  
        const char* name;
        int age;
      public:
        person(const char* n) {
            name = strdup(n);
        }
        ~person() {
            free((void*)name);
        }
        void print() {
            printf("%s is %i\n",name, age);
        }
        int getAge() {
            return this->age;
        }
        void setAge(int a) {
            this->age=a;
        }
    };
    

    为了首先向Lua公开这一点,我将为所有符合Lua函数原型的方法编写包装函数,该原型将Lua状态作为参数,并返回一个int,表示它推送到堆栈上的值的数目(通常为1或0)。

    这些函数中最棘手的是构造函数,它将返回一个类似于对象的Lua表。为此,lua\u newuserdata用于创建指向对象指针的指针。我将假设我们将在Lua init期间创建一个包含这些c函数的元表“Person”。此元表必须与构造函数中的用户数据相关联。

    // wrap the constructor
    int L_newPerson(lua_State* L) {
        //pointer to pointer
        person **p = (person **)lua_newuserdata(L, sizeof(person *));
        //pointer to person
        *p = new person(lua_tostring(L, 1)); 
        // associate with Person meta table
        lua_getglobal(L, "Person"); 
        lua_setmetatable(L, -2); 
        return 1;
    }
    

    int L_print(lua_State* L) {
        person** p = (person**) lua_touserdata(L, 1);
        (*p)->print();
        return 0;
    }
    
    int L_getAge(lua_State* L) {
        person** p = (person**) lua_touserdata(L, 1);
        lua_pushnumber(L, (*p)->getAge());
        return 1;
    }
    
    int L_setAge(lua_State* L) {
        person** p = (person**) lua_touserdata(L, 1);
        (*p)->setAge(lua_tonumber(L, 2));
        return 0;
    }
    

    最后在Lua初始化过程中使用luaL\u寄存器建立Person元表。

    // our methods...
    static const luaL_Reg p_methods[] = {
        {"new", L_newPerson},{"print", L_print},
        {"getAge", L_getAge},{"setAge", L_setAge}, 
        {NULL, NULL}
    };
    
    lua_State* initLuaWithPerson() {
        lua_State* L=lua_open();
        luaL_openlibs(L);
        luaL_register(L, "Person", p_methods);  
        lua_pushvalue(L,-1);
        lua_setfield(L, -2, "__index"); 
        return L;
    }
    

    为了测试它。。。

    const char* Lua_script = 
        "p1=Person.new('Angie'); p1:setAge(25);"
        "p2=Person.new('Steve'); p2:setAge(32);"
        "p1:print(); p2:print();";
    
    int main() {
        lua_State* L=initLuaWithPerson();
        luaL_loadstring(L, Lua_script);
        lua_pcall(L, 0, 0, 0);
        return 0;
    }
    

    在Lua中实现OO还有其他方法。本文介绍了替代方案: http://loadcode.blogspot.com/2007/02/wrapping-c-classes-in-lua.html

        2
  •  4
  •   RBerteig Keith Adler    15 年前

    请参阅Lua用户wiki上关于 binding code to Lua . 有几种技术可以使C++对象从篱笆的Lua侧起作用,其复杂性在于,让LUA持有一个不能直接使用的不透明指针,从而完全暴露了所有C++方法,甚至允许用Lua编写的方法扩展对象。

    对于用C编写的简单函数库,使用luaapi在Lua堆栈和库函数之间移动,手工编写自己的绑定是相当容易的。

    对于一个基于对象的系统来说,手工完成的工作要多得多,因此该页面上列出的其中一个绑定工具将使您的工作更加轻松。

        3
  •  2
  •   Community CDub    8 年前

    我不确定这是不是你要找的,但你试过了吗 luabind ?

    也许 吧 this question 也有帮助。