Python и динамически расширяемые классы C++
Поэтому я столкнулся с проблемой с моими пользовательскими типами, функциями и атрибутами в Python.
Когда я нахожусь в Python, и я хочу установить атрибут для одного из моих пользовательских типов (например, Vector4), мой код получает NULL для const char* attribute_name
аргумент (и да, я импортирую свой модуль).
Как ни странно, когда я жестко кодирую имя атрибута в своей функции установки, я получаю ошибку:
SystemError: error return without exception set
Я вижу, как объект создается в Python (и снова в C++), поэтому я не думаю, что это проблема. Я возвращаю 1, если ловушка setattro успешно установила атрибут в C++, и я вижу, как вызывается код и задает атрибут на стороне C++. Нет ошибок / исключений, которые возникают при установке атрибута.
Кроме того, когда я вызываю функцию в экземпляре моего класса в Python, она вызывает функцию, установленную в tp_getattro
вместо проверки словаря.
Я не совсем уверен, почему, может быть, это потому, что я устанавливаю словарь и помещаю туда свои функции вместо того, чтобы делать это через PyModuleDef
массив, таким образом, функции не видны, когда PyType_Ready
называется.
У кого-нибудь есть идеи, почему это может происходить? Мы используем Python 3.2.
Соответствующий:
У меня базовый тип (tp_new
а также tp_dealloc
), а затем я создаю производные типы во время выполнения. Производные типы имеют словарь, tp_base
, tp_getattro
и tp_setattro
,
Вот как функции связаны с классом / типами Python:
PyMethodDef newMethod;
newMethod.ml_doc = newMethod.ml_name = funcName;
newMethod.ml_flags = METH_VARARGS;
newMethod.ml_meth = pythonFunc;
PyGeneralObj* selfFake = PyObject_New(PyGeneralObj, &MetaEngineType);
selfFake->className = className;
selfFake->funcName = funcName;
Py_INCREF((PyObject*)selfFake);
PyObject *func = PyCFunction_New(&newMethod, (PyObject*)selfFake);
PyObject *method = PyInstanceMethod_New(func);
ErrorIf((method == NULL), "Python: Cannot create instance function. %s",
funcName);
ErrorIf((PyDict_SetItem(classObj->m_pyClassType->tp_dict,
PyReturnStr(newMethod.ml_name), method) == -1),
"Python: Cannot create function in dictionary.");
Py_DECREF(func);
Py_DECREF(method);
Где funcName и className являются константными символами *. pythonFunc - это универсальная функция python, которая обрабатывает вызов всех наших функций, связанных с нашей мета-системой. classObj - указатель на PythonClass, который имеет член m_pyClassType (тип PyTypeObject).
PyGeneralObj
новый объект имеет два const char * и void* (это объект в C++)
я делаю PyType_Ready
и не получить ошибок, а затем увеличить мой тип. Затем я добавляю объект в модуль PyObject, который мне дан PyImport_ImportModule
, Я добавляю свой основной модуль во время выполнения, инициализирую python и импортирую мой модуль.
Если нужно больше информации / кода, я могу опубликовать еще немного. Надеюсь, это имеет смысл, это мой первый пост на stackru.
Для пояснения мы хотим иметь динамические атрибуты, которые полностью разрешаются на стороне C++. И для функций, я хочу иметь возможность переопределить PyObject* self
аргумент, чтобы я мог получить строковое имя функции, которая должна быть вызвана.
Мы не хотим использовать сторонние библиотеки / интерфейсы, такие как Boost, Cython и другие.