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 deletepoint function 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 pointfuncs lua knows it.

    static const lual_reg pointfuncs[] = {   {"new", newpoint},   {"__gc", deletepoint},   {null, null} }; 

Comments

Popular posts from this blog

c# - Send Image in Json : 400 Bad request -

jquery - Fancybox - apply a function to several elements -

An easy way to program an Android keyboard layout app -