anon
anon

Reputation: 42637

c++ classes & lua

I want to have C++ objects that I can read/write in both C++ & Lua.

I have looked at: http://www.lua.org/pil/28.html

However, I do not like that solution, since my objects have constructors & destructors (and they are important as I use RAII and these take care of reference counts).

What I don't like in the PIL solution is that the object is allocated in Lua's heap.

What i want instead, is to create hte C++ object on my own, and just have lua have a way to do get/set on them.

Does anyone have a good tutorial/link on this?

Tanks!

Upvotes: 2

Views: 2423

Answers (4)

ted_j
ted_j

Reputation: 319

I seem to remember a co-worker getting that kind of thing going, both Lua and C++ objects as 1st-class citizens and completely operable in both directions.

If memory serves me right it was based upon Lua++ but at this point I am not sure, sorry.

Upvotes: 1

Alexander Gladysh
Alexander Gladysh

Reputation: 41393

Use the placement new. See here for a handy template:

template< typename T >
void my_newuserdata( lua_State * L ) {
   new ( reinterpret_cast< T * >( lua_newuserdata( L, sizeof( T ) ) ) ) T();
}

template< typename T >
int my_gc( lua_State * l ) {
   reinterpret_cast< T * >( lua_touserdata( L, 1 ) )->~T();
   return 0;
}

(Untested, see link above for details.)

Upvotes: 0

Norman Ramsey
Norman Ramsey

Reputation: 202505

One option is to use a light userdata, which allows you to allocate the object on the C++ heap. See the documentation for lua_pushlightuserdata. Unfortunately a light userdata has no metatable. Even if you are willing to access it using Lua functions to do get/set you still have to do something like this:

static int myget(lua_State *L) {
   myclass thing = lua_touserdata(L, 1);
   lua_pushnumber(thing::getsize());
   return 1;
}

Unfortunately, because it's a light userdata, there's no real way to make this operation type-safe—all light userdata are treated the same, and they have no metatable.

The better solution is to allocate a full userdata on the Lua heap, with a proper metatable, whose contents are a single pointer to the object allocated on the C++ heap. Then you can follow the model in Programming in Lua. For examples you can look at the Lua io library to see how FILE * is handled. This way you can write your C interfaces using the luaL_checkudata function, and they will be safe, but you still will have the right to allocate your objects on the C++ heap instead of on the Lua heap.

Upvotes: 7

dash-tom-bang
dash-tom-bang

Reputation: 17853

Seems like a factory is the way to go? E.g. instead of just dynamically creating your object in Lua via "standard" means, can you call a function for Create and Destroy?

Upvotes: 1

Related Questions