Max Frai
Max Frai

Reputation: 64266

Extract class from python

I'm writing a game in c++ using boost.python library as script system.

I have an abstract class Object. Now I create new class, inherit it from Objects and write somewhere Object *obj = new SomeCoolObject();

I also have a map of objects: map<string, Object*> objects. So after making object I do: objects.insert("name", obj);.

Don't say anything about freeing memory, etc. I hided that part to get less code (I'm using smart pointers).

So the question is:

I want to have a folder with python-files. In each file I describe some Object-derived class like:

class SomeCoolObject(Object):
   ...

How to bind that class into c++? Or in another words: how to say into c++ program that there is such new class.

And once again: there colud be a few py-files with such classes and I have to export all of them.

Any ideas, guys?

Upvotes: 0

Views: 1586

Answers (1)

Jeremy Sandell
Jeremy Sandell

Reputation: 435

If you've already loaded the module (e.g., using boost::python::import("module_name")), you should be able to reference any classes in it via the attr() member function. Generally I write a wrapper function around it, since it can raise an exception if the class (or any other attribute, for that matter) doesn't exist. For example:

boost::python::object getattr(const boost::python::object &obj, const std::string &name)
{
    try
    {
        return obj.attr(boost::python::str::str(name));

    }
    catch(const boost::python::error_already_set &err)
    {
        /* we need to fetch the error indicators *before*
         * importing anything, as apparently importing
         * using boost python clears the error flags.
         */

        PyObject *e, *v, *t;
        PyErr_Fetch(&e, &v, &t);

        boost::python::object AttributeError = boost::python::import("exceptions").attr("AttributeError");

        /* Squash the exception only if it's an AttributeError, otherwise
         * let the exception propagate.
         */
        if (PyErr_GivenExceptionMatches(AttributeError.ptr(), e))
            return boost::python::object(); // None

        else
            throw;
    }
}

[... later in the code ...]

using namespace boost::python;

object main_module = import("__main__");
object main_namespace = main_module.attr("__dict__");


object your_module = import("module_name");
object your_class = getattr(main_namespace, "SomeCoolObject");

// Now we can test if the class existed in the file
if (!your_class.is_none())
{
     // it exists! Have fun.
}

Upvotes: 1

Related Questions