I am using tolua++ to export some C++ classes to Lua.
My understanding that each class is 'implemented' on the lua side,开发者_如何转开发 as a lua table. I am wondering if it is possible therefore, to add new (Lua) methods to the C++ object table so that I can achieve the effect of adding new methods to the C++ class.
Assume that I am exporting the class Foobar.
Methods of Foobar will be accessisble in Lua as follows:
Foobar:method1()
Foobar:method2()
...
etc.
I would like to be able to add new methods (newmethod1, and newmethod2) to the Foobar table "object"
I have the following questions:
- Is it possible to 'extend' the functionality of an exported C++ object in the manner I described above?
- How would one go about add new functions to the Foobar table? (I am relatively new to Lua)
Yes, It is possible to add new methods to an existing exported class.
Foobar is just a plain table, so you can attach methods onto it as you would any other table. [1]
Foobar["extra_method"] = function (self, arg1, arg2) print(arg1, arg2) end
and now you can do:
Foobar:extra_method(1,2)
and 1 2
will be displayed.
[1] tolua++ works somewhat oddly. It creates one main table for each class, which is what you see as Foobar, that holds both the static member functions of the class (e.g. Foobar:new()
) and the instance member functions of the class (e.g. what Foobar:method1()
likely is). The :
operator in lua is syntactic sugar; a:b()
is converted to a.b(a)
. This means when you call Foobar:new()
, it is transposed to Foobar:new(Foobar)
, thus the self
argument is the Foobar table. When you create an object of type Foobar, and then call method1() on it, self
will be that object. Thus, adding a new method method3
to the Foobar table will allow you to do Foobar:method3()
and obj = Foobar:new(); obj:method3()
, although the former will give an error. Thus, this answer only works for tolua++.
Edit: to address comment
Let me use actual code here. So let's assume we have a class declaration of Foobar that looks like:
class Foobar {
public:
void method1();
static void method2();
};
When tolua++ generates the lua binding code for this class it's going to give you a table with the following methods
- new() - Call as
Foobar:new()
to create an instance of Foobar. - delete() - Call as
instance:delete()
to destroy an instance of Foobar. - method1() - Call as
instance:method1()
to run method1 on instance. - method2() - Call as
Foobar:method2()
to run method2.
However, tolua++ doesn't actually use two different tables (one for the methods that should be attached to the class itself and one for the methods of the instance of that class). Instead, it merges the two together, so it's possible to run Foobar:method1()
and instance:new()
... even though that's not how the methods should be used. Thus, there is no difference between how static methods are used and how instance methods are used. Syntactically, it's also the same. (I personally feel that this is a problem with tolua++.)
If you're looking for an example, here is how you should be calling these functions from within lua:
obj = Foobar:new()
print( obj:method1() )
obj:delete()
精彩评论