How to extract C++ object pointer from Lua -
i have class in c++ called "point":
class point { public:   int x, y;    //constructor   point(int x, int y)   {     this->x = x;     this->y = y;   } };   my goal able instantiate point object lua script, , extract pointer object lua stack.
here (currently not working) attempt clarifies trying do; note code modified copy/paste this tutorial , using lua 5.2:
static int newpoint(lua_state *l)  {     int n = lua_gettop(l);     if (n != 2)         return lual_error(l, "expected 2 args point.new()", n);       // allocate memory pointer object     point **p = (point **)lua_newuserdata(l, sizeof(point *));        double x = lual_checknumber (l, 1);           double y = lual_checknumber (l, 2);       //i want access pointer in c++ outside function     *p = new point(x, y);      lual_getmetatable(l, "point"); // use global table 'point' metatable     lua_setmetatable(l, -2);     return 1;  }  static const lual_reg pointfuncs[] = {   {"new", newpoint},   {null, null} };  //register point lua void registerpoint(lua_state *l) {     lua_createtable(l, 0, 0);     // register metatable user data in registry     lual_newmetatable(l, "point");     lual_setfuncs(l, pointfuncs, 0);                lua_pushvalue(l,-1);     lua_setfield(l,-2, "__index");     lua_setglobal(l, "point"); }  point* checkpoint(lua_state* l, int index) {   void* ud = 0;   lual_checktype(l, index, lua_ttable);    lua_getfield(l, index, "__index");   ud = lual_checkudata(l, index, "point");;      return *((point**)ud);       }   int main()  {     lua_state *l = lual_newstate();     lual_openlibs(l);         registerpoint(l);     lual_dofile(l, "testz.lua");     lua_getglobal(l, "point");     point *foo = checkpoint(l, lua_gettop(l));         std::cout << "x: " << foo->x << " y: " << foo->y;     lua_close(l);     return 0;  }   and here lua script:
local point = point.new(10,20)   running code, following error: "bad argument #3 (point expected, got table)" @ line: ud = lual_checkudata(l, index, "point") inside checkpoint() function.
if 1 steer me in right direction, appreciated.
there couple of issues in above usage , binding.
inside testing script, local point will not seen host c++ program. because, well, it's local script. if want accessible c++, either return point value script or make global , retrieve using lua_getglobal(l, "point").
the checkpoint function has unnecessary code. if @ other lual_check* functions provided lua c api, check if given value @ stack index right type. if convert type on c++ can use.
so in 'checkpoint' function need is:
point* checkpoint(lua_state* l, int index) {   return *((point **) lual_checkudata(l, index, "point")); }   if change script this, example:
local point = point.new(10,20) return point   you should able access point c++ in following way:
// ... lual_dofile(l, "testz.lua");  point *foo = checkpoint(l, -1); std::cout << "x: " << foo->x << " y: " << foo->y; // ...   another important point regarding c++ object lifetime when exposed lua. because you're allocating , constructing c++ 'new' operator whenever point.new called script, indirectly saying let lua handle exposed c++ object's lifetime. means you'll want implement __gc metamethod act 'finalizer' or non-deterministic destructor. without have no way 'delete' point object , reclaim space when lua garbage collects corresponding userdata.
to can augment code follows:
write
deletepointfunction gets called lua on userdata gc.static int deletepoint(lua_state *l) { pointer **p = checkpoint(l, 1); delete *p; *p = null; // not needed safe return 0; }add
pointfuncslua knows it.static const lual_reg pointfuncs[] = { {"new", newpoint}, {"__gc", deletepoint}, {null, null} };
Comments
Post a Comment