c调用python , 有参无参

1. c语言调用python 的步骤

1.1 包含头文件

#include <Python.h>

1.2 初始化Python解释器

void Py_Initialize();

1.3 添加当前路径到sys.path 中

  • 导入sys模块
使用  PyObject *PyImport_ImportModule(const char *name)  导入
  • 获取sys.path对象
*PyObject_GetAttrString(PyObject *o, const char *attr_name)		获取
  • 将当前路径.添加到sys.path中
int PyList_Append(PyObject *list, PyObject *item)

1.4 导入要调用的模块

PyObject *PyImport_ImportModule(const char *name)

1.5 获取函数对象

PyObject *PyObject_GetAttrString(PyObject *o, const char *attr_name)

1.5.1 检查函数对象是否可被调用

int PyCallable_Check(PyObject *obj)

1.6 构造参数

PyObject *Py_BuildValue(const char *format, ...)

调用此函数创建一个Python元组或者对象作为Python函数的参数,无参数不需要调用。
C和Python的数据类型转换对应的格式:
在这里插入图片描述

1.7 调用函数并获取返回值

PyObject *PyObject_CallObject(PyObject *callable, PyObject *args)

1.8 返回值解析

int PyArg_Parse(PyObject *args, const char *format, ...)

1.9 释放引用的所有python对象

void Py_DECREF(PyObject *o)

1.10 关闭python解释器

void Py_Finalize()

2. 调用无参函数示例

printenv.py

# 无参函数
def fun_noparam():
    print("Hello C")
getpython.c

#include <Python.h>

int main() {
    /*初始化python解释器 */
    Py_Initialize();   

    /* 添加当前路径到sys.path 中 */ 
    // sys模块在Python中提供了对Python解释器的一些变量和功能的访问,例如命令行参数或系统路径等
    PyObject *sys = PyImport_ImportModule("sys");      //从Python的标准库中导入名为sys的模块,并将返回的对象赋值给指针sys
    //从sys模块对象中获取名为path的属性,并将其赋值给指针path。在Python中,sys.path是一个列表,包含了Python解释器在导入模块时会搜索的路径
    PyObject *path = PyObject_GetAttrString(sys, "path"); 
    // 使用`PyUnicode_FromString`函数将C字符串`"."`转换为一个Python的unicode对象。这里的`.`表示当前目录。  
    // 使用`PyList_Append`函数将上述创建的unicode对象添加到`path`列表中。在Python中,这相当于执行`sys.path.append('.'),
    //即将当前目录添加到Python模块的搜索路径中。
    PyList_Append(path, PyUnicode_FromString("."));

    /* 导入要调用的python模块 printenv.py*/
    PyObject *pModel = PyImport_ImportModule("printenv");
    if (!pModel) {
        // 当 Python C API 函数遇到错误时,它们通常会设置一个异常对象,但并不会自动打印错误信息。
        // PyErr_Print() 函数用于检索当前线程中的异常对象,并打印其类型、值和 traceback(如果有的话)。
        PyErr_Print();
        printf("error: load python model faild\n");
        return 1;
    }

    /* 获取导入模块中的函数对象 */ 
    PyObject *pFunc = PyObject_GetAttrString(pModel, "fun_noparam");
    // PyCallable_Check(pFunc) 是 Python C API 中的一个宏,用于检查一个 Python 对象是否可以被调用。
    // 这个宏检查对象是否实现了 Python 的 __call__ 方法,使得它可以像函数那样被调用。
    // pFunc 是一个指向 Python 对象的指针,通常是一个 PyObject* 类型的变量。
    // 这个宏返回一个整数,如果对象是可调用的,返回非零值(通常是 1),否则返回 0。
    if (!pFunc || !PyCallable_Check(pFunc)) {
        PyErr_Print();
        printf("error: python model function fun_noparam() faild\n");
        return 1;
    }

    /* 调用fun_noParam 函数并获取返回值*/
    PyObject *pValue = PyObject_CallObject(pFunc, NULL);
    if (!pValue) {
        PyErr_Print();
        printf("error: function call faild\n");
        return 1;
    }

    /* 释放所有引用的python对象*/
    Py_DECREF(pValue);
    Py_DECREF(pFunc);
    Py_DECREF(pModel);

    /* 关闭Python 解释器 */
    Py_Finalize();

    return 0;
}

编译:

gcc getpython.c -o getpyNoParam -I /usr/include/python3.10 -l python3.10

运行结果:
在这里插入图片描述

3. 调用有参函数示例

parameter.py

# 有参函数
def func_param(param):
    print(param)
    return param
getPythonParam.c

#include <Python.h>

int main() {
    Py_Initialize();

    PyObject *sys = PyImport_ImportModule("sys");
    PyObject *path = PyObject_GetAttrString(sys, "path");
    PyList_Append(path, PyUnicode_FromString("."));

    PyObject *pmode = PyImport_ImportModule("parameter");
    if (!pmode) {
        PyErr_Print();
        printf("error: load python model faild\n");
        return 1;
    }

    PyObject *pFunc = PyObject_GetAttrString(pmode, "func_param");
    if (!pFunc || !PyCallable_Check(pFunc)) {
        PyErr_Print();
        printf("error: python model function func_param() faild\n");
        return 1;
    }

    // 创建一个字符串作为函数参数
    char *param = "this c transmit param";
    PyObject *pArgs = Py_BuildValue("(s)", param);   // 构建元组

    // 调用带参python 函数并获取返回值
    PyObject *result = PyObject_CallObject(pFunc, pArgs);
    if (!result) {
        PyErr_Print();
        printf("error: function call faild\n");
    }

    // 将返回类型转为c类型
    char *resultToC = NULL;
    if (!PyArg_Parse(result, "s", &resultToC)) {
        PyErr_Print();
        printf("error: parse return param faild\n");
    }

    // 打印返回值
    printf("return param: %s\n", resultToC);

    /* 释放所有引用的python对象*/
    Py_DECREF(result);
    Py_DECREF(pFunc);
    Py_DECREF(pmode);

    /* 关闭Python 解释器 */
    Py_Finalize();

    return 0;
}

编译:

gcc getpythonParam.c -o getpyParam -I /usr/include/python3.10 -l python3.10

运行结果:
在这里插入图片描述

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不知所云,

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值