如何利用c调用python代码

C语言调用python 通过C语言调用Python代码,需要先安装libpython3的 dev依赖库(不同的ubuntu版本下,python版本 可能会有差异, 比如ubuntu 22.04里是libpyt...

C语言调用python

通过C语言调用Python代码,需要先安装libpython3的 dev依赖库(不同的ubuntu版本下,python版本 可能会有差异, 比如ubuntu 22.04里是libpython3.10-dev)。 首先可以通过以下命令验证是否是否已经存在python3的dev包

dpkg -l | grep libpython3

正常会有类似如下的输出,出现"libpython3"和 "dev",如libpython3.10-dev即可

如果没有, 可以通过apt命令安装相关的dev包:

sudo apt install libpython3.10-dev

调用无参python函数

#nopara.py文件

def say_funny():

print('funny')

用C语言进行调用无参python代码的流程

包含Python.h头文件,以便使用Python API。

使用void Py_Initialize()初始化Python解释器,

使用PyObject *PyImport_ImportModule(const char *name)和PyObject *PyObject_GetAttrString(PyObject *o, const char *attr_name)获取sys.path对象,并利用 int PyList_Append(PyObject *list, PyObject *item)将当前路径.添加到sys.path中,以便加载 当前的Python模块(Python文件即python模块)。

使用PyObject *PyImport_ImportModule(const char *name)函数导入Python模块,并检查是否 有错误。

使用PyObject *PyObject_GetAttrString(PyObject *o, const char *attr_name)函数获取 Python函数对象,并检查是否可调用。

使用PyObject *PyObject_CallObject(PyObject *callable, PyObject *args)函数调用 Python函数,并获取返回值。

使用void Py_DECREF(PyObject *o)函数释放所有引用的Python对象。

结束时调用void Py_Finalize()函数关闭Python解释器。 相关的函数参数说明参考网站(网站左上角输入函数名即可开始搜索)。

示例代码

#include

int main(int argc, char const *argv[])

{

Py_Initialize();

PyObject *sys = PyImport_ImportModule("sys");

PyObject *path = PyObject_GetAttrString(sys,"path");

PyList_Append(path,PyUnicode_FromString("."));

PyObject *pModule = PyImport_ImportModule("nopara");

if(!pModule){

PyErr_Print();

printf("ERROR:failed to load nopara.py\n");

}

PyObject *pFunc = PyObject_GetAttrString(pModule,"say_funny");

if(!pFunc || !PyCallable_Check(pFunc))

{

PyErr_Print();

printf("ERROR:function say_funny not found or not callable\n");

return 1;

}

PyObject *pValue = PyObject_CallObject(pFunc,NULL);

if(!pValue)

{

PyErr_Print();

printf("ERROR: function call failed\n");

return 1;

}

Py_DECREF(pValue);

Py_DECREF(pFunc);

Py_DECREF(pModule);

Py_Finalize();

return 0;

}

调用有参python函数

定义一个带参数和返回值的函数

#para.py

def say_funny(category):

print(category)

return category

用C语言进行调用有参python代码的流程

包含Python.h头文件,以便使用Python API。

使用void Py_Initialize()初始化Python解释器,

使用PyObject *PyImport_ImportModule(const char *name)和PyObject *PyObject_GetAttrString(PyObject *o, const char *attr_name)获取sys.path对象,并利用 int PyList_Append(PyObject *list, PyObject *item)将当前路径.添加到sys.path中,以便加载 当前的Python模块(Python文件即python模块)。

使用PyObject *PyImport_ImportModule(const char *name)函数导入Python模块,并检查是否 有错误。

使用PyObject *PyObject_GetAttrString(PyObject *o, const char *attr_name)函数获取 Python函数对象,并检查是否可调用。

使用PyObject *Py_BuildValue(const char *format, ... x )函数将C类型的数据结构转换成 Python对象,作为Python函数的参数,没有参数不需要调用

这里要注意的是,Py_BuildValue的第一个参数是类型转换:C对应的Python的数据类型转换对应的格式 如下:

使用PyObject *PyObject_CallObject(PyObject *callable, PyObject *args)函数调用 Python函数,并获取返回值。

使用int PyArg_Parse(PyObject *args, const char *format, ...)函数将返回值转换为C类 型,并检查是否有错误,没有返回值时不需要调用。

使用void Py_DECREF(PyObject *o)函数释放所有引用的Python对象。

结束时调用void Py_Finalize()函数关闭Python解释器。 相关的函数参数说明参考网站(网站左上角输入函数名即可开始搜索)。

示例代码

#include

int main(int argc, char const *argv[])

{

Py_Initialize();

// 将当前路径添加到sys.path中

PyObject *sys = PyImport_ImportModule("sys");

PyObject *path = PyObject_GetAttrString(sys,"path");

PyList_Append(path,PyUnicode_FromString("."));

// 导入para模块

PyObject *pModule = PyImport_ImportModule("para");

if(!pModule){

PyErr_Print();

printf("ERROR:failed to load para.py\n");

}

//获取say_funny函数对象

PyObject *pFunc = PyObject_GetAttrString(pModule,"say_funny");

if(!pFunc || !PyCallable_Check(pFunc))

{

PyErr_Print();

printf("ERROR:function say_funny not found or not callable\n");

return 1;

}

//创建一个字符串作为参数

char *category = "comedy";

PyObject *pArgs = Py_BuildValue("(s)",category);

//调用say_funny函数并获取返回值

PyObject *pValue = PyObject_CallObject(pFunc,pArgs);

if(!pValue)

{

PyErr_Print();

printf("ERROR: function call failed\n");

return 1;

}

//将返回值转换为C类型

char *result = NULL;

if(!PyArg_Parse(pValue,"s",&result))

{

PyErr_Print();

printf("Error: parse failed\n");

}

//打印返回值

printf("pValue=%s\n",result);

//释放所有引用的Python对象

Py_DECREF(pValue);

Py_DECREF(pFunc);

Py_DECREF(pModule);

//释放所有引用的Python对象

Py_Finalize();

return 0;

}