Python将任意非调用方/非自类实例传递给C
我正在实现一个通用优先级队列,它将Python将任意非调用方/非自类实例传递给C,python,c++,ctypes,typeerror,Python,C++,Ctypes,Typeerror,我正在实现一个通用优先级队列,它将ints作为键,将任何类实例作为元素;将这些任意对象称为节点。该算法将在Python中原型化,但在C++中实现。我试图找出python接口部分。下面是C++代码< /p> queue.c++ #include <Python.h> #include <vector> #include <iostream> class PQueue { public: PQueue() { Q = std::v
int
s作为键,将任何类实例作为元素;将这些任意对象称为节点。该算法将在Python中原型化,但在C++中实现。我试图找出python接口部分。下面是C++代码< /p>
queue.c++
#include <Python.h>
#include <vector>
#include <iostream>
class PQueue
{
public:
PQueue()
{
Q = std::vector<PyObject *>();
}
void insert(PyObject *node)
{
Q.push_back(node);
std::cout << "Added a node" << std::endl;
}
private:
std::vector<PyObject *> Q;
};
extern "C"
{
PQueue *PQueue_new()
{ return new PQueue(); }
void PQueue_insert(PQueue *self, PyObject *n) /* This fails */
{ self->insert(n); }
}
变量n
是表示节点的任意类实例。我想使用PyObject_CallMethodObjArgs访问n
的成员变量,但由于以下错误,我无法访问:
lib.PQueue_insert(self.obj, n );
ctypes.ArgumentError: argument 2: <class 'TypeError'>: Don't know how to convert parameter 2
lib.pqueu_插入(self.obj,n);
ctypes.ArgumentError:参数2::不知道如何转换参数2
我知道python类不是C原语,但
PyObject
的存在让我相信这样的事情应该是可能的。ctypes可以将其转换为ctypes.py\u对象(n)
,但是,在C++库使用<代码> pyObjt*/Cux>指针时,需要在Python中保留引用,以防止对象变得未被引用和解除分配。此外,要真正调用Python对象的方法,您的库必须首先获取全局解释器锁(GIL)。您也可以,而且可能应该,使用Python的C API编写一个C扩展模块。是的,它现在可以正常工作了。你应该发布一个答案,而不仅仅是一个评论,这样我就可以把答案分配给你了。我需要在python中保留一个引用,这感觉像是在浪费空间;有办法解决这个问题吗?也许两个程序可以共享一个公共列表/数组对象。至于C扩展模块,上面的代码不是一个非常简单的C扩展模块吗?更不用说我刚刚发现了Py_INCREF
和Py_DECREF
。当引用计数达到0时,Py_DECREF
和Py_XDECREF
宏调用类型的tp_dealoc>。你需要为这件事负责。如果我是你,我只会写一个.cType,可以将它转换为<代码> cType。pyyObjult(n),但是你需要在Python中保存一个引用,以防止对象在C++库使用<代码> pyObjs*/Cux>指针时变得不被引用和解除分配。此外,要真正调用Python对象的方法,您的库必须首先获取全局解释器锁(GIL)。您也可以,而且可能应该,使用Python的C API编写一个C扩展模块。是的,它现在可以正常工作了。你应该发布一个答案,而不仅仅是一个评论,这样我就可以把答案分配给你了。我需要在python中保留一个引用,这感觉像是在浪费空间;有办法解决这个问题吗?也许两个程序可以共享一个公共列表/数组对象。至于C扩展模块,上面的代码不是一个非常简单的C扩展模块吗?更不用说我刚刚发现了Py_INCREF
和Py_DECREF
。当引用计数达到0时,Py_DECREF
和Py_XDECREF
宏调用类型的tp_dealoc>。你需要为这件事负责。如果我是你,我会写一篇真实的文章。
lib.PQueue_insert(self.obj, n );
ctypes.ArgumentError: argument 2: <class 'TypeError'>: Don't know how to convert parameter 2