Ошибка при компиляции CPython: не удается преобразовать из PyLongObject в PyObject

#python #c #cpython

#python #c #cpython

Вопрос:

Я пытался научиться использовать CPython и для этого я попытался создать простую факториальную функцию. Вот функция:

 /*
long factorial(long number){
    long output = 1;

    for (long i = 1; i < number; i  ){
        output *= i;}}
*/

PyLongObject factorial(PyLongObject number){

    PyLongObject output = PyLong_FromLong(1);

    for (PyLongObject i = PyLong_FromLong(1); PyObject_RichCompare(i, number, Py_LT); PyNumber_InPlaceAdd(1, i)){
        PyNumber_InPlaceMultiply(i, output);}
    return output;
}
  

Однако, когда я компилирую программу с использованием setup.py файла, я получаю следующую ошибку:

 error C2440: 'function': cannot convert from 'PyLongObject' to 'PyObject *'
warning C4024: 'PyObject_RichCompare': different types for formal and actual parameter 1
warning C4024: 'PyObject_RichCompare': different types for formal and actual parameter 2
warning C4024: 'PyNumber_InPlaceAdd': different types for formal and actual parameter 1
warning C4024: 'PyNumber_InPlaceAdd': different types for formal and actual parameter 2
error C2440: 'function': cannot convert from 'PyLongObject' to 'PyObject *'
warning C4024: 'PyNumber_Multiply': different types for formal and actual parameter 1
warning C4024: 'PyNumber_Multiply': different types for formal and actual parameter 2
error C2440: '=': cannot convert from 'PyObject *' to 'PyLongObject'
error C2440: 'initializing': cannot convert from 'PyObject *' to 'PyLongObject'
error C2440: 'initializing': cannot convert from 'PyObject *' to 'PyLongObject'
error C2440: 'initializing': cannot convert from 'PyObject *' to 'PyLongObject'
error: command 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.27.29110\bin\HostX86\x64\cl.exe' failed with exit status 2
  

Я предполагаю, что это потому, что я неправильно использую PyLongObject и PyObject* . Я попытался просмотреть документы CPython, чтобы попытаться найти проблему, но не смог понять, что я делаю неправильно. Как я могу исправить свой код, чтобы он работал?

Примечание: я использую объекты Python, потому что они обеспечивают мне произвольную точность длины.

Хорошо, итак, я исправил код для правильной компиляции, но я понятия не имею, почему. Это то, на что я его изменил:

 PyObject* factorial(PyObject* number){

    PyObject* output = PyLong_FromLong(1);

    for (PyObject* i = PyLong_FromLong(1); PyObject_RichCompare(i, number, Py_LT); PyNumber_InPlaceAdd(1, i)){
        PyNumber_InPlaceMultiply(i, output);}
    return output;
}
  

Почему этот код работает сейчас?

Ответ №1:

Ссылка на C-Api

Проверьте документацию.

 PyObject* PyObject_RichCompare(PyObject *o1, PyObject *o2, int opid)
  

Первый и второй аргументы имеют тип PyObject *, ранее вы передавали PyLongObject .
т.е. i и number

Компилятор говорил вам именно это. То же объяснение относится и к другим вызовам функций. Когда вы изменили код, все вызовы функций теперь получают параметры с ожидаемым типом.

Комментарии:

1. Аааа, хорошо. Сначала я думал, что PyLongObject является подклассом класса PyObject и что передача его вместо этого была в порядке. Спасибо за вашу помощь!