3

This is rather tricky to explain and I could not find anything on this in the documentation or anywhere on the net so I thought this would be a suitable place for this question.

I'm trying to register properties and methods on an object in Lua using C++.

This is what I'm trying to achieve in Lua:

player = createPlayer()
player:jump() // method
player.x = player.x + 3 // properties

I can easily achieve the first line in the example using C++

int create_player(lua_State *L)
{
    Player* player = new Player();
    ..

    return 0;
}

int main(int args, char * argv[])
{
    lua_State* L = lua_open();
    luaL_openlibs(L);    

    lua_register(L, "createPlayer", create_player);

    luaL_dofile(L, "main.lua");

    ..
    return 0;
}

But how do I create the method :jump() and properties .setX and .getX for createPlayer?

hichris123
  • 10,145
  • 15
  • 56
  • 70
  • There are multiple options, but basically, for the methods you can go either the user type or the lua table way (in which you place CFunctions) and for the properties you need to go the metatable way. I advise you to look into several available wrappers, that make this easier for you. – user1095108 Aug 07 '14 at 15:24
  • I want to get into the direct source rather than wrappers. How can I do this with CFunctions? – user3806521 Aug 07 '14 at 15:34
  • It is a too broad question for someone to answer and it is well covered online, as well as books even. Look into the wrappers or google for an answer. Many pages cover this topic. – user1095108 Aug 07 '14 at 15:52
  • Perhaps you could point me in the right direction then, rather than wrappers, what would be a good search? – user3806521 Aug 07 '14 at 15:53
  • 1
    A great place to start is the Programming in Lua book. The 1st edition is available for free. This section should help: http://www.lua.org/pil/28.html – Adam Aug 07 '14 at 16:25
  • 2
    This wiki has everything you need http://lua-users.org/wiki/BindingCodeToLua but you'll reinvent the wheel. – user1095108 Aug 07 '14 at 16:44
  • Have a look at [this answer of mine](http://stackoverflow.com/questions/22515908/using-straight-lua-how-do-i-expose-an-existing-c-class-objec-for-use-in-a-lua/22558439#22558439). Perhaps it will guide you in the right direction (don't be shy to upvote, if it does ;). – W.B. Aug 07 '14 at 18:35
  • don't roll your own, use [luabridge](http://vinniefalco.com/LuaBridge/Manual.html) or [luabind](http://www.rasterbar.com/products/luabind.html) or more modern alternatives that are abundant on github or at the link posted by @user1095108 – Dmitry Ledentsov Aug 08 '14 at 13:18

1 Answers1

-1

What you could have searched is "Binding C++ to Lua".

Since it's a rather popular question, I'll post an answer with a project compilable online:

Starting from a C++ class:

class Player {
  int x;
public:
  Player() : x(0) {}
  int get_x() const { return x; }
  void set_x(int x_) { x = x_; }
  void jump() {}
};

You can then create bindings using LuaBridge without writing the boilerplate for each of the bound members yourself:

void luabridge_bind(lua_State *L) {
 luabridge::getGlobalNamespace(L)
 .beginClass<Player>("Player")
  .addConstructor<void (*)(), RefCountedPtr<Player> /* shared c++/lua lifetime */ >()
  .addProperty("x", &Player::get_x, &Player::set_x)
  .addFunction("jump", &Player::jump)
 .endClass()
 ; 
}

Using a dedicated Lua State wrapper LuaState, you can then open a Lua state and perform the bindings:

lua::State state;
luabridge_bind(state.getState());

Running the script using some trace output:

try {
  static const char *test =
  "player = Player() \n"
  "player:jump() \n"
  "player.x = player.x + 3"
  ;
  state.doString(test);
}
catch (std::exception &e) {
  std::cerr << e.what() << std::endl;
}

Produces the following output:

Player
jump
get_x
set_x 3
~Player

You can see the whole thing live at Travis-CI

Dmitry Ledentsov
  • 3,620
  • 18
  • 28