- Exposing A C++ Class To Lua Download
- Exposing A C++ Class To Lua Programming
- Expose C++ Class To Lua
- Exposing A C++ Class To Luau
In addition to binding C++ functions and classes with Lua, luabind also providean OO-system in Lua.
Lua's API is not designed to register C classes to Lua, only C functions that have the signature int(luaState.), that is, a function that takes an luaState pointer as an argument and returns an integer. Actually, that is the only C data type that Lua supports in registering. LuaFunctionWrapper.h contains a static class wrapping Lua methods with a templated methods. This way, you can call 'generic' get / set methods and in background, correct Lua methods are called (luatounsigned, luatonumber etc.). LuaClassBind.h contains a helper class for binding C class to Lua. Its content is used to build C class.
Inheritance can be used between lua-classes:
The base class is initialized explicitly by calling its __init()function.
As you can see in this example, you can call the base class member functions.You can find all member functions in the base class, but you will have to givethe this-pointer (self) as first argument.
Deriving in lua¶
It is also possible to derive Lua classes from C++ classes, and overridevirtual functions with Lua functions. To do this we have to create a wrapperclass for our C++ base class. This is the class that will hold the Lua objectwhen we instantiate a Lua class.
Important
Since MSVC6.5 doesn’t support explicit template parametersto member functions, instead of using the member function call()you call a free function call_member() and pass the this-pointeras first parameter.
Note that if you have both base classes and a base class wrapper, you must giveboth bases and the base class wrapper type as template parameter toclass_ (as done in the example above). The order in which you specifythem is not important. You must also register both the static version and thevirtual version of the function from the wrapper, this is necessary in orderto allow luabind to use both dynamic and static dispatch when calling the function.
Important
It is extremely important that the signatures of the static (default) functionis identical to the virtual function. The fact that one of them is a freefunction and the other a member function doesn’t matter, but the parametersas seen from lua must match. It would not have worked if the static functiontook a base_wrapper* as its first argument, since the virtual functiontakes a base* as its first argument (its this pointer). There’s currentlyno check in luabind to make sure the signatures match.
If we didn’t have a class wrapper, it would not be possible to pass a Lua classback to C++. Since the entry points of the virtual functions would still pointto the C++ base class, and not to the functions defined in Lua. That’s why weneed one function that calls the base class’ real function (used if the luaclass doesn’t redefine it) and one virtual function that dispatches the callinto luabind, to allow it to select if a Lua function should be called, or ifthe original function should be called. If you don’t intend to derive from aC++ class, or if it doesn’t have any virtual member functions, you can registerit without a class wrapper.
You don’t need to have a class wrapper in order to derive from a class, but ifit has virtual functions you may have silent errors.
The wrappers must derive from luabind::wrap_base, it contains a Lua referencethat will hold the Lua instance of the object to make it possible to dispatchvirtual function calls into Lua. This is done through an overloaded member function:
Its used in a similar way as call_function, with the exception that it doesn’ttake a lua_State pointer, and the name is a member function in the Lua class.
Warning
The current implementation of call_member is not able to distinguish constmember functions from non-const. If you have a situation where you have an overloadedvirtual function where the only difference in their signatures is their constness, thewrong overload will be called by call_member. This is rarely the case though.
Note
You can also override virtual member functions per instance which oftenmakes it unnecessary to derive a new class in Lua. Instead of e.g.
Exposing A C++ Class To Lua Download
you may be able to get around with
Object identity¶
When a pointer or reference to a registered class with a wrapper is passedto Lua, luabind will query for it’s dynamic type. If the dynamic typeinherits from wrap_base, object identity is preserved.
This functionality relies on RTTI being enabled (that LUABIND_NO_RTTI isnot defined).
Exposing A C++ Class To Lua Programming
Overloading operators¶
You can overload most operators in Lua for your classes. You do this by simplydeclaring a member function with the same name as an operator (the name of themetamethods in Lua). The operators you can overload are:
- __add
- __sub
- __mul
- __div
- __pow
- __lt
- __le
- __eq
- __call
- __unm
- __tostring
- __len
__tostring isn’t really an operator, but it’s the metamethod that is calledby the standard library’s tostring() function. There’s one strange behaviorregarding binary operators. You are not guaranteed that the self pointer youget actually refers to an instance of your class. This is because Lua doesn’tdistinguish the two cases where you get the other operand as left hand value orright hand value. Consider the following examples:
This will work well as long as you only subtracts instances of my_class witheach other. But If you want to be able to subtract ordinary numbers from yourclass too, you have to manually check the type of both operands, including theself object.
The reason why __sub is used as an example is because subtraction is notcommutative (the order of the operands matters). That’s why luabind cannotchange order of the operands to make the self reference always refer to theactual class instance.
If you have two different Lua classes with an overloaded operator, the operatorof the right hand side type will be called. If the other operand is a C++ classwith the same operator overloaded, it will be prioritized over the Lua class’operator. If none of the C++ overloads matches, the Lua class operator will becalled.
Finalizers¶
If an object needs to perform actions when it’s collected we provide a__finalize function that can be overridden in lua-classes. The__finalize functions will be called on all classes in the inheritancechain, starting with the most derived type.
Slicing¶
If your lua C++ classes don’t have wrappers (see Deriving in lua) andyou derive from them in lua, they may be sliced. Meaning, if an objectis passed into C++ as a pointer to its base class, the lua part will beseparated from the C++ base part. This means that if you call virtualfunctions on that C++ object, they will not be dispatched to the luaclass. It also means that if you adopt the object, the lua part will begarbage collected.
The problem can be illustrated by this example:
Expose C++ Class To Lua
In lua:
In this example, lua cannot know that b actually is the same object asa, and it will therefore consider the object to be owned by the C++ side.When the b pointer then is adopted, a runtime error will be raised becausean object not owned by lua is being adopted to C++.
Exposing A C++ Class To Luau
If you have a wrapper for your class, none of this will happen, seeObject identity.