Binding functions of derived class with luabind - c++

I am currently developing a plugin-based system in C++ which provides a Lua scripting interface, for which I chose to use luabind. I'm using Lua 5 and luabind 0.9, both statically linked and compiled with MSVC++ 8. I am now having trouble binding functions with luabind when they are defined in a derived class, but not its parent class.
More specifically, I have an abstract base class called 'IPlugin' from which all plugin classes inherit. When the plugin manager initialises, it registers that class and its functions like this:
luabind::open(L);
luabind::module(L) [
luabind::class_<IPlugin>("IPlugin")
.def("start", &IPlugin::start)
];
As it is only known at runtime what effective plugin classes are available, I had to solve loading plugins in a kind of roundabout way. The plugin manager exposes a factory function to Lua, which takes the name of a plugin class and a desired object name. The factory then creates the object, registers the plugin's class as inheriting from the 'IPlugin' base class, and immediately calls a function on the created object that registers itself as a global with the Lua state, like this:
void PluginExample::registerLuaObject(lua_State *L, string a_name)
{
luabind::globals(L)[a_name] = (PluginExample*)this;
}
I initially did this because I had problems with Lua determining the most derived class of the object, as if I register it from the plugin manager it is only known as a subtype of 'IPlugin' and not the specific subtype. I'm not sure anymore if this is even necessary though, but it works and the created object is subsequently accessible from Lua under 'a_name'.
The problem I have, though, is that functions defined in the derived class, which were not declared at all in the parent class, cannot be used. Virtual functions defined in the base class, such as 'start' above, work fine, and calling them from Lua on the new object runs the respective redefined code from the 'PluginExample' class. But if I add a new function to 'PluginExample', here for example a function taking no arguments and returning void, and register it like this:
luabind::module(L) [
luabind::class_<PluginExample, IPlugin>("PluginExample")
.def(luabind::constructor<PluginManager&>())
.def("func", &PluginExample::func)
];
calling 'func' on the new object yields the following Lua runtime error:
No matching overload found, candidates:
void func(PluginExample&)
I am correctly using the ':' syntax so the 'self' argument is not needed and it seems suddenly Lua cannot determine the derived type of the object anymore. I am sure I am doing something wrong, probably having to do with the two-step binding required by my system architecture, but I can't figure out where. I'd much appreciate some help =)

Related

How can I register a C++ class and function in Lua 5.3

So I've been using this game engine for quite some time, I can create a game using that with either the built-in events or I can use C++ but I've recently tried to embed Lua 5.3 to it, but I'm having problems on how to register a certain C++ class to Lua, example:
In the game engine's C++, I would change the background color like this:
#include "GDCpp/RuntimeScene.h"
void changeBackground(RuntimeScene & scene)
{
scene.SetBackgroundColor(250,100,85)
}
But my problem is, how can I do that in Lua ? how can I register that function and class in Lua 5.3?
Hava a look on this example.
You create/request a metatable with the class name, push member functions (except constructor) into him and register a constructor function which returns your class as userdata, linked with the metatable.
Setting field "__index" on self table is required that later member access leads to the metatable, not userdata. "__gc" happens on garbage collection - your destructor. Because Lua is written in C, allocating userdata memory doesn't invoke constructors, so the class instance was put on the heap and the address passed to Lua.

Performing "true" dynamic casts at runtime?

So I am still working on a flexible scripting system for this school project and have come to a road block. The problem is this: I have a script state manager interface that any scripting state will implement (currently implementing lua, but want to be able to add python later). It has pure virtual functions for things such as DoFile, DoString, RegisterObject and RegisterFunction. So the LuaStateManager implements this interface using luaplus classes and encapsulates the LuaState object as it should.
So when an object registers itself with lua and throws all its methods into a metatable I have to do something like this:
metaTable.RegisterObjectDirect(“Move”, (Actor*)0, &Actor::Move);
This would be fine if I had access to the underlying state object in the StateManager interface as it would be getting called from the Actor class itself so the cast could be guaranteed. Unfortunately, I need to somehow pass this info to the LuaState::RegisterFunction method so the I don't have to expose the LuaState object and couple my classes to it. As far as I can see though, there is no way to pass information about which type of class to cast to.
Does any body have any suggestions? I thought about trying to use a templated function to perform the cast, but I know that you can't have function pointers to templates, so that is out the window. Thanks!

How to create a Python Object from a C++ Object using Boost.Python

I have a C++ project that use a lot of classes. The main one is 'sso::Object' (every classes are in the 'sso' namespace) and this class is derived into some other classes but one which is abstract: 'sso::Drawable'.
This class has two pure virtual methods 'sso::Drawable::set_opacity' and 'sso::Drawable::raw_draw' and it is derived into other classes like 'sso::View' which implement these two methods.
The whole project works fine when it is used in C++, but I would like to use it in Python too, so I created a Boost.Python module like that:
class DrawableWrapper : public sso::Drawable , public wrapper<sso::Drawable> {
public:
void set_opacity(byte opacity) { this->get_override("set_opacity")(opacity); }
void raw_draw(const sso::Rect &rect,sso::Target &target,const sso::Position &position) const {
this->get_override("raw_draw")(rect,target,position);
}
};
BOOST_PYTHON_MODULE(sso) {
class_<DrawableWrapper,boost::noncopyable> ("Drawable",init<>())
.add_property ("opacity",&sso::Drawable::get_opacity)
// python_sso_getter & python_sso_setter_* are only used for an easier access to accessors
.add_property ("position",python_sso_getter<sso::Drawable,sso::Position,&sso::Drawable::get_position>,python_sso_setter_1_const<sso::Drawable,sso::Position,&sso::Drawable::set_position>)
.def("raw_draw",pure_virtual(&sso::Drawable::raw_draw))
;
class_<sso::View,bases<sso::Drawable> > ("View",init<>())
.def("insert",python_sso_setter_1<sso::View,sso::Drawable*,&sso::View::insert>)
.def("remove",&sso::View::erase)
;
}
This code compile without errors but when I execute these lines in Python:
myview = sso.View()
print myview
I get this output:
<sso.View object at 0x7f9d2681a4b0>
But my C++ debugger tell me that the variable 'v' (the python 'myview') is a 'sso::Object' instance, not a 'sso::View' one. sso::View::View() is called but the variable type is not a view and I don't know why. Do you have any idea about that ? Did you do something like that and found a way to make it work ?
I use Python2.7 and Boost.Python1.49 and gcc version 4.6.1
EDIT: I've made a mistake: sso::Drawable does not inherit from sso::Object, but sso::View does (=multiple inheritance).
The output <sso.View object at 0x7f9d2681a4b0> from python is just python telling you what it thinks the object type is called, it has nothing to do with the actual type of object created at the C++ level.
As you've told boost python to expose the object as sso.View then that is what python will see it as. If you were to change your code to expose std::string as sso.View then python would still report <sso.View object at 0x7f9d2681a4b0> after you've created it.
Similarly, if you were to change "View" in your C++ to "BlahDeBlah" then python would report the object as <sso.BlahDeBlah object at 0x7f9d2681a4b0> (of course you'd also have to create it via sso.BlahDeBlah()
That aside, I can't see anything wrong with the code you have posted. Does sso::View inherit from sso::Object? If that's the case, and you've witnessed sso::view::View() being called, then I think you might just be misinterpreting the debugger when it tells you the object is of type sso::Object. Perhaps it has a pointer to the base class or something similar at the point you are debugging?
What happens when you call myview.insert or myview.remove from python?
EDIT: I suspect (though I could be wrong) that you might not have RTTI turned on in your compiler, so typeid() is just returning the type that implemented the function you are in when you called typeid(). That would certainly explain why you get sso::View when in insert but a different answer in other functions.
Anyway, I've been looking into the documentation a little bit more and I think your problem is actually that you've provided the ability to override the raw_draw method but you haven't actually overridden it with anything.
If you have a look at the decleration of the pure_virtual boost::python function at the bottom of this file you'll see a comment:
//
// Passed a pointer to member function, generates a def_visitor which
// creates a method that only dispatches to Python if the function has
// been overridden, either in C++ or in Python, raising a "pure
// virtual called" exception otherwise.
//
So what you're seeing is just expected behaviour. If you provide an override for raw_draw in sso::View or a python class that inherits from it then you should no longer get this error.

Objects vs instance in python

In C++ there are just objects and classes, where objects are instances of classes.
In Python, a class definition (i.e., the body of a class) is called an object.
And, the object in C++ is called instance in python.
Check this
Am I wrong?
EDIT : Actually can someone explain with example difference of object vs instance
EDIT : In python, everything will inherit from object class & hence everything is an object (i.e object of object class).
A Class is also an object (i.e object of object class).
Instance is the name used to call the object of any class.(a.k.a c++ object).
Please refer this
In Python, a class definition (i.e., the body of a class) is called an object
Actually, this is still called a class in Python. That's why you define it like this:
class Foo(object):
pass
The class keyword is used because the result is still called a class.
The word object is in parentheses to show that Foo is derived from the class called object. Don't be confused -- any existing class could be used here; more than one, in fact.
The reason you usually derive classes from object is a historical accident but probably is worth a detail. Python's original object implementation treated user-defined classes and built-in types as slightly different kinds of things. Then the language's designer decided to unify these two concepts. As a result, classes derived from object (or from a descendant of object) behave slightly differently from classes that are not derived from object and are called new-style classes. Old-style classes, on the other hand, were ones defined like this:
class Foo:
pass
class Bar(Foo):
pass
Note these do not inherit from object or from anything else that inherits from object. This makes them old-style classes.
When working with Python 2.x, your classes should almost always inherit from object, as the new-style objects are nicer to work with in several small but important ways.
To further confuse things, in Python 3.0 and later, there are no old-style classes, so you don't have to derive from object explicitly. In other words, all the above classes would be new-style classes in Python 3.x.
Now, back to the matter at hand. Classes are objects because everything is an object in Python. Lists, dictionaries, integers, strings, tuples... all of these are objects, and so are the building blocks of Python programs: modules, functions, and classes. You can create a class using the class keyword and then pass it to a function, modify it, etc. (For completeness, you can also create a class using the type() function.)
A class is a template for building objects, which are referred to as instances. This part you already know. You instantiate objects similar to calling a function, passing in the initial values and other parameters:
mylist = list("abc") # constructs ["a", "b", "c"]
Behind the scenes, this creates an instance, then calls the new instance's __init__() method to initialize it. Since everything's an object in Python, instances of a class are also objects.
One last thing you might want to know is that just as classes are templates for building objects, so it is possible to have templates for building classes. These are called metaclasses. The base metaclass is called type (that is, an ordinary new-style class is an instance of type).
(Yes, this is the same type that I mentioned earlier can be used to create classes, and the reason you can call it to create classes is that it's a metaclass.)
To create your own metaclass, you derive it from type like so:
class mymeta(type):
pass
Metaclasses are a fairly advanced Python topic, so I won't go into what you might use them for or how to do it, but they should make it clear how far Python takes the "everything's an object" concept.
Terminology-wise, classes and instances are both called objects in Python, but for you as a regular Python programmer this is of no importance. You can see Python's classes and instances pretty much as C++'s classes and instances:
class MyClass:
data = 1
mc = MyClass()
MyClass is a class and mc is an instance of class MyClass.
Python is much more dynamic in nature than C++ though, so its classes are also objects. But this isn't something programmers usually are exposed to, so you can just not worry about it.
Everything in Python is an object. Even classes, which are instances of metaclasses.
Since you asked for "english please", I'll try to make it simple at the cost of detail.
Let's ignore classes and instances at first, and just look at objects.
A Python object contains data and functions, just like objects in every other object oriented programming language. Functions attached to objects are called methods.
x = "hello" #now x is an object that contains the letters in "hello" as data
print x.size() #but x also has methods, for example size()
print "hello".size() #In python, unlike C++, everything is an object, so a string literal has methods.
print (5).bit_length() #as do integers (bit_length only works in 2.7+ and 3.1+, though)
A class is a description (or a recipe, if you will) of how to construct new objects. Objects constructed according to a class description are said to belong to that class. A fancy name for belonging to a class is to be an instance of that class.
Now, earlier I wrote that in Python everything is an object. Well, that holds for stuff like functions and classes as well. So a description of how to make new objects is itself an object.
class C: #C is a class and an object
a = 1
x1 = C() #x1 is now an instance of C
print x1.a #and x1 will contain an object a
y = C #Since C is itself an object, it is perfectly ok to assign it to y, note the lack of ()
x2 = y() #and now we can make instances of C, using y instead.
print x2.a #x2 will also contain an object a
print C #since classes are objects, you can print them
print y #y is the same as C.
print y == C #really the same.
print y is C #exactly the same.
This means that you can treat classes (and functions) like everything else and, for example, send them as arguments to a function, which can use them to construct new objects of a class it never knew existed.
In a very real sense, everything in Python is an object: a class (or any
type) is an object, a function is an object, a number is an object...
And every object has a type. A "type" is a particular type of object (a
class, if you wish), with additional data describing the various
attributes of the type (functions, etc.). If you're used to C++, you
can think of it as something like:
struct Type;
struct Object // The base class of everything.
{
Type* myType;
// Some additional stuff, support for reference counting, etc.
};
struct Type : Object
{
// Lots of additional stuff defining type attributes...
};
When you define a new class in Python, you're really just creating a new
instance of Type; when you instantiate that class, Python initializes
the myType member with a pointer to the correct instance of Type.
Note, however, that everything is dynamic. When you define a type
Toto (by executing a class definition—even defining a type is a
runtime thing, not compile time, as in C++), the Python interpreter
creates an instance of Type, and puts it in a dictionary
(map<string, Object*>, in C++ parlance) somewhere. When the interpreter
encounters a statement like:
x = Toto()
, it looks up Toto in the dictionary: if the Object referred to has
the type Type, it constructs a new instance of that object, if it has
type Function (functions are also objects), it calls the function.
(More generally, a type/class may be callable or not; if the type of the
Object found in the dictionary under Toto is callable, the Python
interpreter does whatever the object has defined "call" to mean. Sort
of like overloading operator()() in C++. The overload of
operator()() for Type is to construct a new object of that type.)
And yes, if you come from a classical background—strictly procedural,
structured, fully-compiled languages, it can be pretty confusing at
first.

JNI non-Java class members

I want to create a Java wrapper against some third-party library with C interface. The library operates on a complex Context entity which is essentially a C++ object (C++ is used internally in that library, but API is in pure C). It would be natural to wrap this entity into a class accessible from Java. For that, a pointer to Context should be stored somewhere.
I see two options to do this:
to declare a new member on java side (as long, for example) and convert it to pointer type inside JNI methods implementation
to declare a new member in JNI header (That might be illegal if Java relies on the size of structure it gerenated for me by javah)
All the tutorials on JNI are too simple to give me a hint on how to wrap a complex entities with Java classes, any links on more verbose documentation are appreciated.
I also want to know where it is appropriate to call Context destruction function (C++ destructor inside) I don't want to use Java finalize for that as Java don't favor finalize methods and I supect there is a way to define a destruction procedure on native side.