编译CPython时出错:无法从PyLongObject转换为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,output);}
    return output;
}

为什么此代码现在可以正常工作?

解决方法

C-Api reference

检查文档。

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

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

编译器正完全告诉您。其他函数调用也有相同的解释。更改代码后,所有函数调用现在都将接收具有预期类型的​​参数。