Извлечь класс из Python - PullRequest
       16

Извлечь класс из Python

0 голосов
/ 22 марта 2011

Я пишу игру на c ++, используя библиотеку boost.python в качестве системы сценариев.

У меня есть абстрактный класс Object. Теперь я создаю новый класс, наследую его от Objects и пишу куда-то Object *obj = new SomeCoolObject();

У меня также есть карта объектов: map<string, Object*> objects. Итак, после создания объекта я делаю: objects.insert("name", obj);.

Не говорите ничего об освобождении памяти и т. Д. Я скрыл эту часть, чтобы получить меньше кода (я использую умные указатели).

Итак, вопрос:

Я хочу иметь папку с python-файлами. В каждом файле я описываю некоторый класс Object, например:

class SomeCoolObject(Object):
   ...

Как связать этот класс с C ++? Или другими словами: как сказать в программе на С ++, что существует такой новый класс.

И еще раз: в таких классах есть несколько py-файлов, и я должен экспортировать их все.

Есть идеи, ребята?

1 Ответ

1 голос
/ 24 марта 2011

Если вы уже загрузили модуль (например, используя boost::python::import("module_name")), вы сможете ссылаться на любые классы в нем с помощью функции-члена attr().Обычно я пишу функцию-обертку вокруг нее, так как она может вызвать исключение, если класс (или любой другой атрибут, в этом отношении) не существует.Например:

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.
}
...