You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Python函数作为参数传入C/C++扩展实现的Python函数

错误原因

你解析得到的f_py是Python函数对象在C层面的指针,并非原生C函数指针,不能直接用C的f_py(5)语法调用,必须通过Python C API提供的调用接口完成函数调用、返回值解析操作。

正确实现代码

修改后的f_cpp函数如下:

static PyObject* f_cpp(PyObject* self, PyObject* args) {
    PyObject* f_py;
    if (!PyArg_ParseTuple(args, "O", &f_py)) {
        return NULL;
    }
    // 校验传入的对象是否是可调用类型
    if (!PyCallable_Check(f_py)) {
        PyErr_SetString(PyExc_TypeError, "parameter must be a callable function");
        return NULL;
    }
    // 调用Python函数,传入整数参数5
    PyObject* ret = PyObject_CallFunction(f_py, "i", 5);
    // 检查函数调用是否出错
    if (ret == NULL) {
        return NULL;
    }
    // 将Python返回的浮点数转为C的double类型
    double x = PyFloat_AsDouble(ret);
    // 检查类型转换是否出错
    if (PyErr_Occurred()) {
        Py_DECREF(ret);
        return NULL;
    }
    // 释放返回值的引用,避免内存泄漏
    Py_DECREF(ret);
    // 执行自定义C函数逻辑并返回结果
    return PyFloat_FromDouble(f(x));
}

关键逻辑说明

  • PyCallable_Check 用于校验传入的对象是否是可调用类型,避免传入非函数对象时程序崩溃
  • PyObject_CallFunction 是Python提供的C API,用于调用Python可调用对象,第二个参数为参数格式符,"i"表示后续传入一个C int类型作为Python函数的参数
  • 调用Python函数得到的返回值是PyObject*类型,需要通过PyFloat_AsDouble转换为C语言原生的double类型
  • 所有通过Python C API生成的新对象(这里指ret)使用完成后必须调用Py_DECREF减少引用计数,避免内存泄漏

内容的提问来源于stack exchange,提问作者Sergey Revkov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 08:36:03