#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:
Проверьте документацию.
PyObject* PyObject_RichCompare(PyObject *o1, PyObject *o2, int opid)
Первый и второй аргументы имеют тип PyObject *, ранее вы передавали PyLongObject .
т.е. i и number
Компилятор говорил вам именно это. То же объяснение относится и к другим вызовам функций. Когда вы изменили код, все вызовы функций теперь получают параметры с ожидаемым типом.
Комментарии:
1. Аааа, хорошо. Сначала я думал, что PyLongObject является подклассом класса PyObject и что передача его вместо этого была в порядке. Спасибо за вашу помощь!