编译 CPython 时出错:无法从 PyLongObject 转换为 PyObject

Error when compiling CPython: Cannot Convert from PyLongObject to PyObject

我一直在尝试学习使用 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

我猜这是因为我没有正确使用 PyLongObjectPyObject*。我试着查看 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;
}

为什么这段代码现在有效?

C-Api reference

查看文档。

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

第一个和第二个参数是 PyObject* 类型,之前您传递的是 PyLongObject。 即我和数字

编译器告诉你的正是这一点。同样的解释也适用于其他函数调用。当您更改代码时,所有函数调用现在都接收具有预期类型的​​参数。