Python和动态扩展c++类

Python and Dynamically Extending C++ Classes

本文关键字:c++ 扩展 动态 Python      更新时间:2023-10-16

所以我在Python中遇到了自定义类型,函数和属性的问题。

当我在Python中,我想在我的一个自定义类型(例如Vector4)上设置一个属性时,我的代码为const char* attribute_name参数获得NULL(是的,我正在导入我的模块)。

奇怪的是,当我在setter函数中硬编码属性名时,我得到了错误:

SystemError: error return without exception set

我确实看到对象在Python中被创建(又在c++中),所以我不认为这是问题所在。如果setattro钩子在c++中成功地设置了属性,我确实返回1,并且我看到代码被调用并在c++端设置了属性。设置属性时不会引发错误/异常。

另外,当我在Python中调用类的实例上的函数时,它会调用tp_getattro中的函数集,而不是检查字典。

我不完全确定为什么,也许是因为我设置了一个字典并把我的函数放在那里,而不是通过PyModuleDef数组来做,因此当PyType_Ready被调用时,函数不被看到。

有人知道为什么会发生这种情况吗?我们正在使用Python 3.2。


相关:

我有一个基本类型(tp_newtp_dealloc),然后我在运行时创建派生类型。派生类型有一个字典,tp_base, tp_getattrotp_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为const char*。pythonFunc是一个泛型python函数,用于处理所有绑定到元系统的函数的调用。classObj是一个指向PythonClass的指针,该PythonClass有一个成员m_pyClassType (PyTypeObject的类型)。

PyGeneralObj是一个新对象,有两个const char*和一个void*(这是c++中的对象)

我执行PyType_Ready,没有得到错误,然后增加我的类型。然后,我将对象添加到我从PyImport_ImportModule给出的模块PyObject中。我把我的主模块附加到运行时中,初始化python并导入我的模块。


如果需要更多的信息/代码,我可以发布更多。我希望这有意义,这是我第一次在stackoverflow上发帖。

澄清一下,我们想要拥有在c++端完全解析的动态属性。对于函数,我希望能够覆盖PyObject* self参数,以便我可以获得需要调用的函数的字符串名称。

我们不希望使用第三方库/接口,如Boost, Cython等。

问题出在我的getattro实现中