views:

705

answers:

1

I am using Luabind to expose a base class from C++ to Lua from which I can derive classes in Lua. This part works correctly and I am able to call C++ methods from my derived class in Lua.

Now what I want to do is obtain a pointer to the Lua-based instance in my C++ program.

C++ -> Binding

class Enemy {
private:
  std::string name;

public:
  Enemy(const std::string& n) 
    : name(n) { 
  }

  const std::string& getName() const { 
    return name; 
  }

  void setName(const std::string& n) { 
    name = n; 
  }

  virtual void update() { 
    std::cout << "Enemy::update() called.\n"; 
  }
};

class EnemyWrapper : public Enemy, public luabind::wrap_base {
public:
  EnemyWrapper(const std::string& n) 
    : Enemy(n) { 
  }

  virtual void update() { 
    call<void>("update"); 
  }

  static void default_update(Enemy* ptr) {
    ptr->Enemy::update();
  }

};

// Now I bind the class as such:
module(L)
[
class_<Enemy, EnemyWrapper>("Enemy")
  .def(constructor<const std::string&, int>())
    .property("name", &Enemy::getName, &Enemy::setName)
    .def("update", &Enemy::update, &EnemyWrapper::default_update)
];

Lua-based Derived Class

class 'Zombie' (Enemy)

function Zombie:__init(name)
    Enemy.__init(self, name)
end

function Zombie:update()
    print('Zombie:update() called.')
end

Now let's say I have the following object created from Lua:

a = Zombie('example zombie', 1)

How can I get a reference of that object as a pointer to the base class in C++?

+4  A: 

If in Lua you do

zombie = Zombie('example zombie', 1)

then you can get the value of the zombie like this:

object_cast<Enemy*>(globals(L)["zombie"]);

(object_cast and globals are members of the luabind namespace, L is your Lua state) This assumes you know the names of the variables you create in Lua.

You can always call a C++ method from Lua that takes a pointer to Enemy:

void AddEnemy(Enemy* enemy) { /* ... */ }
//...
module(L) [ def("AddEnemy", &AddEnemy) ]

and call it from Lua

a = Zombie("zombie", 1);
AddEnemy(a)

Be aware that if you do

AddEnemy(Zombie("temp zombie", 1));

Lua will delete the "temp zombie" after the method call and invalidate any pointers to the object.

sbk
Thanks! This did the trick. Thanks also for the tip about the "temp zombie". Can this garbage collecting be worked around by using smart/shared pointers?
Zack Mulgrew
@Zack: I would say yes, but I haven't tried it.
sbk
@sbk, I cleaned up the formatting. SO's Markdown apparently doesn't like code paragraphs near bullet lists, so I dropped the bullets in favor of having the code be clear. I put the Lua code in `<pre>` tags without indent for consistency with the C++ code.
RBerteig