编译CPython时出错:C2440'函数':无法从'PyObject'转换为PyObject *'

问题描述

我是使用cpython(以及C)的新手,我试图创建一个扩展模块来计算nCk。但是,编译时遇到了这个非常烦人的错误。这是我的代码

PyObject* combination(PyObject* n,PyObject* k){
    PyObject* output = ONE;
    return PyNumber_TrueDivide(factorial(n),PyNumber_Multiply(factorial(k),factorial(PyNumber_Subtract(n,k))));
}
static PyObject* BezierCurve_combination(PyObject* self,PyObject* args){
    PyObject n,k;

    if (!PyArg_ParseTuple(args,"OO",&n,&k))
        return NULL;
    
    /* This return statement is line 60*/
    return Py_BuildValue("O",combination(n,k));
}

这是错误消息:

(60): error C2440: 'function': cannot convert from 'PyObject' to 'PyObject *'
(60): warning C4024: 'combination': different types for formal and actual parameter 1
(60): warning C4024: 'combination': different types for formal and actual parameter 2

是什么导致此错误一个类似的程序对于阶乘函数定义确实很好用(它只包含1个PyObject*参数。)如何解决这个问题?

解决方法

您永远不能在程序中有这样的PyObject。它们始终是PyObject的指针。

使用PyObject *n,*k;-或如有疑问,

PyObject *n;
PyObject *k;

此外,您必须始终检查Python异常中的每个每个函数的返回值,除非您只是返回从您的功能。因此,您可能不会写

return PyNumber_TrueDivide(factorial(n),PyNumber_Multiply(factorial(k),factorial(PyNumber_Subtract(n,k))));

你只能写

return PyNumber_TrueDivide(dividend,divisor);

对于内部调用,您必须分别检查它们是否不是NULL,如果是,则表示必须处理或抛出(通过从函数返回NULL)抛出异常。