2012-08-10 43 views
0

我正在编写就地添加操作的实现。但是,出于某种原因,我有时会得到一个只读缓冲区(当我添加一个自定义扩展类和一个整数时...)。实现nb_inplace_add导致返回只读缓冲区对象

相关的代码是:

static PyObject * 
ModPoly_InPlaceAdd(PyObject *self, PyObject *other) 
{ 

    if (!ModPoly_Check(self)) { 
     //Since it's in-place addition the control flow should never 
     // enter here(I suppose) 
     if (!ModPoly_Check(other)) { 
      PyErr_SetString(PyExc_TypeError, "Neither argument is a ModPolynomial."); 
      return NULL; 
     } 
     return ModPoly_InPlaceAdd(other, self); 
    } else { 
     if (!PyInt_Check(other) && !PyLong_Check(other)) { 
      Py_INCREF(Py_NotImplemented); 
      return Py_NotImplemented; 
     } 
    } 

    ModPoly *Tself = (ModPoly *)self; 
    PyObject *tmp, *tmp2; 
    tmp = PyNumber_Add(Tself->ob_item[0], other); 
    tmp2 = PyNumber_Remainder(tmp, Tself->n_modulus); 

    Py_DECREF(tmp); 
    tmp = Tself->ob_item[0]; 
    Tself->ob_item[0] = tmp2; 
    Py_DECREF(tmp); 
    return (PyObject *)Tself; 

} 

如果不是返回(PyObject*)Tself(或简称“自我”),我抛出一个异常,原来的对象得到正确更新[使用一些printf检查。如果我使用Py_RETURN_NONE宏,它会正确地将ModPoly转换为None(在Python一侧)。

我在做什么错?我返回一个指向ModPoly对象的指针,这怎么会成为一个缓冲区?我没有看到这些指针的任何操作。

用法示例:

>>> from algebra import polynomials 
>>> pol = polynomials.ModPolynomial(3,17) 
>>> pol += 5 
>>> pol 
<read-only buffer ptr 0xf31420, size 4 at 0xe6faf0> 

我试图改变返回线进入:

printf("%d\n", (int)ModPoly_Check(self)); 
return self; 

和添加时,它打印1就地(也就是说,返回的值是ModPolynomial类型...)

回答

1

根据the documentation,对象的就地添加操作返回一个新的引用。

通过直接返回self而不需要调用Py_INCREF就可以了,当它仍然被引用时,你的对象将被释放。如果某个其他对象被分配了相同的内存块,则这些引用现在将为您提供新对象。

+0

你说得对。这是我的第一个C扩展,因此我仍然试图了解何时应该使用INCREF/DECREF。 – Bakuriu 2012-08-10 09:17:34