Я пишу реализацию операции добавления на месте. Но по какой-то причине я иногда получаю только буфер только для чтения (в то время как я добавляю собственный класс расширения и целое число ...).Реализация результатов 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
...)
Вы правы. Это мое первое C-расширение, поэтому я все еще пытаюсь понять, когда я должен делать INCREF/DECREF. – Bakuriu