Python C++ 扩展单例

Posted

技术标签:

【中文标题】Python C++ 扩展单例【英文标题】:Python C++ extension Singleton 【发布时间】:2014-10-24 14:24:51 【问题描述】:

我正在尝试为 Python (3.x) 编写一个 C++ 扩展,它允许我为 Raspberry Pi 使用特定的硬件屏蔽。 我在编写 C 和/或 C++ 方面没有任何经验,但是使用 Python 网站上的文档,我实际上得到了工作。我想做的是让我的类型成为单例,但如果 init 方法返回错误 (-1),那么对构造函数的第二次调用就会搞砸。如果 init 返回没有错误,它实际上按预期工作。

我的代码的重要部分:

static PyObject *
MyType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)

    static MyType *self = NULL;  /* static to create a Singleton */

    if (self == NULL) 
        self = (MyType *)type->tp_alloc(type, 0);

        self->is_initialized = false;
    
    else 
        Py_XINCREF(self);
    

    return (PyObject *)self;


static int
MyType_init(MyType *self, PyObject *args, PyObject *kwds)

    const char *i2c_addr;

    self->rpi_model = RPI_MODEL_B;
    self->enabled_components = COMPONENTS_ALL_BIT;

    static char *kwlist[] = "rpi_model", "enabled_components", NULL;

    if (self != NULL && !self->is_initialized) 
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwlist, &self->rpi_model, &self->enabled_components)) 

            return -1;
        
    

    /*
        DO SOME INITIALIZATION STUFF
    */

    if (!self->component_A->testConnection()) 
        PyErr_SetString(InitializationException, "Unable to communicate with component_A.");
        return -1;
    

    self->is_initialized = true;
    return 0;

我还在 tp_dealloc 成员中安装了以下功能:

static void
MyType_dealloc(PyObject *self)

    Py_TYPE(self)->tp_free((PyObject*)self);

我在这些方法中添加了一些打印语句(用于调试),似乎在第二次调用 MyType_new 时,self != NULL,尽管在初始化失败时已执行 MyType_dealloc 方法。

有人能指出我正确的方向吗?

【问题讨论】:

【参考方案1】:

您的MyType_dealloc 似乎没有将self 设置回NULL

另外,您无需同时拥有__new____init__ -- 只需将其全部放入__new__

【讨论】:

以上是关于Python C++ 扩展单例的主要内容,如果未能解决你的问题,请参考以下文章

Python设计模式——单例模式

Python:C++ 扩展返回多个值

C++使用boost.python编写Python扩展

如何在 boost::python 扩展模块中正确组合 C++ 和 Python 代码?

如何使用纯 Python 扩展 API (python3) 包装 C++ 对象?

为 Python 创建 C++ 扩展