C语言中程序如何调用Python脚本

有时候在写C语言程序的时候又想利用一下python强大的模块,于是C与python的混合编程便应运而生。
下面简单说说在C语言编译环境中调用python脚本文件的基础应用。

一、环境配置

以vs2017为例。

0x00 平台

首先你要知道你电脑上安装的python环境是64位还是32位,vs的编译平台需要与python环境一致。
比如我的python环境是64位,vs工程就要配置成x64。

右键点击你的解决方案,点击属性,

0x01 添加 包含目录 和 库目录

在属性窗口双击“VC++ Directories”(VC++目录),把在Include Directories (包含目录)和 Library Directories(库目录)下添加python安装路径下的include和ibs文件夹的路径。

0x02 添加依赖项

在添加之前一定要先确保自己安装了python的debug版本,详见我的另一篇博客【VS2017】“LNK1104 cannot open file ‘python39_d.lib‘

双击“linker”(链接器)下的“Input”,添加python39_d.lib这个依赖项

点击确定则配置完成。

这样在写程序的时候添加Python.h头文件就不会报错,python39_d.lib里的API函数也就可以正常使用了。

二、案例

主要流程就是:

  • 初始化python
  • 导入py脚本(模块)
  • 获取模块里的函数
  • 必要的C语言数据类型转python的数据类型(传参前)
  • 调用函数
  • 释放python
#include<stdio.h>
#include <Python.h>
int main()
{
	PyObject *pName, *pModule, *pDict, *pFunc;
	PyObject *pArgs, *pValue;
	//待传参数
	int time[6]={1,2,3,4,5,6};
	//初始化python
	Py_Initialize();
	// 检查初始化是否成功
	if (!Py_IsInitialized())
	{
		printf("初始化失败\n");
		Py_Finalize();
	}
	//设置python模块,搜寻位置,文件放在.c文件一起
	PyRun_SimpleString("import sys");
	PyRun_SimpleString("sys.path.append('./')");

	//获取python文件名,导入模块(我这里的py文件是graph.py)
	pModule = PyImport_ImportModule("graph");
	if (!pModule) {
		printf("py文件导入失败\n");
		Py_Finalize();
	}
	else {
		//直接获取模块中的函数
		pFunc = PyObject_GetAttrString(pModule, "create_graph");
		//验证函数是否获取成功
		if (!pFunc) {
			printf("函数导入失败\n");
			Py_Finalize();
		}

		//将c/c++类型数据转换为python类型,利用元组传递
		pArgs = PyTuple_New(6);
		pValue = PyLong_FromLong(time[0]);
		PyTuple_SetItem(pArgs, 0, pValue);

		pValue = PyLong_FromLong(time[1]);
		PyTuple_SetItem(pArgs, 1, pValue);

		pValue = PyLong_FromLong(time[2]);
		PyTuple_SetItem(pArgs, 2, pValue);

		pValue = PyLong_FromLong(time[3]);
		PyTuple_SetItem(pArgs, 3, pValue);

		pValue = PyLong_FromLong(time[4]);
		PyTuple_SetItem(pArgs, 4, pValue);

		pValue = PyLong_FromLong(time[5]);
		PyTuple_SetItem(pArgs, 5, pValue);

		//调用直接获得的函数,并传递参数
		pValue = PyObject_CallObject(pFunc, pArgs);

		//释放python
		Py_Finalize();

		printf("success");
		return 0;
	}
}

顺便给出我的graph.py的脚本,这是一个以参数的数值生成对应的excel文件的脚本,这两个源代码是根据我的另一篇关于排序算法的博文改的案例。

# -*- coding:utf-8 -*-
import xlsxwriter

def create_graph(a,b,c,d,e,f):
	# 创建一个excel
	workbook = xlsxwriter.Workbook("排序算法比较结果.xlsx")
	# 创建一个sheet
	worksheet = workbook.add_worksheet()
	# worksheet = workbook.add_worksheet("bug_analysis")

	# 自定义样式,加粗
	bold = workbook.add_format({'bold': 1})

	# --------1、准备数据并写入excel---------------
	# 向excel中写入数据,建立图标时要用到
	headings = ["排序方法", "排序时间"]
	data = [["简单选择排序", "直接插入排序", "冒泡排序", "快速排序", "两路合并排序", "堆排序"],[a,b,c,d,e,f]]

	# 写入表头
	worksheet.write_row('A1', headings, bold)

	# 写入数据
	worksheet.write_column('A2', data[0])
	worksheet.write_column('B2', data[1])

	# --------2、生成图表并插入到excel---------------
	# 创建一个柱状图(column chart)
	chart_col = workbook.add_chart({'type': 'column'})

	# 配置第一个系列数据
	chart_col.add_series({'name': '=Sheet1!$B$1','categories': '=Sheet1!$A$2:$A$7','values':   '=Sheet1!$B$2:$B$7','line': {'color': 'red'},})
	# 这里的sheet1是默认的值,因为我们在新建sheet时没有指定sheet名
	# 如果我们新建sheet时设置了sheet名,这里就要设置成相应的值

	# 设置图表的title 和 x,y轴信息
	chart_col.set_title({'name': "排序算法结果"})
	chart_col.set_x_axis({'name': "排序方法"})
	chart_col.set_y_axis({'name':  "花费时间(ms)"})

	# 设置图表的风格
	chart_col.set_style(1)

	# 把图表插入到worksheet以及偏移
	worksheet.insert_chart('A10', chart_col, {'x_offset': 25, 'y_offset': 10})

	workbook.close()
	return 0

if __name__=="__main__":
	create_graph(10, 40, 50, 20, 10, 50)

三、常用API

1、运行Python指令

PyRun_SimpleString("print(os.getcwd(),a)");
pyext.eval(R"(a+='qwer')");

2、加载Python模块

PyObject * pModule =PyImport_ImportModule("tp"); //test:Python文件名,若脚本有错则返回空
PyRun_SimpleString("import os");

3、给Python的变量赋值

对于数值,使用Py_BuildValue:

Py_BuildValue("") None
Py_BuildValue("i", 123) 123
Py_BuildValue("iii", 123, 456, 789) (123, 456, 789)
Py_BuildValue("s", "hello") 'hello'
Py_BuildValue("ss", "hello", "world") ('hello', 'world')
Py_BuildValue("s#", "hello", 4) 'hell'
Py_BuildValue("()") ()
Py_BuildValue("(i)", 123) (123,)
Py_BuildValue("(ii)", 123, 456) (123, 456)
Py_BuildValue("(i,i)", 123, 456) (123, 456)
Py_BuildValue("[i,i]", 123, 456) [123, 456]
Py_BuildValue("{s:i,s:i}", "abc", 123, "def", 456) {'abc': 123, 'def': 456}

对于其他数据结构,使用相应的函数设置,例如:

PyObject *pArgs = PyTuple_New(1);
PyObject *pDict = PyDict_New();  //创建字典类型变量
PyDict_SetItemString(pDict, "Name", Py_BuildValue("s", "YQC")); //往字典类型变量中填充数据
PyDict_SetItemString(pDict, "Age", Py_BuildValue("i", 25)); //往字典类型变量中填充数据
PyTuple_SetItem(pArgs, 0, pDict);//0---序号 将字典类型变量添加到参数元组中

构造好对象以后,通过PyObject_SetAttrString来设置进入Python中:

PyObject *ps=PyUnicode_DecodeUTF8(val,strlen(val),"ignore"); //构造了一个对象
PyObject_SetAttrString(p_main_Module,key,ps); //设置

4、获取Python变量的值

首先取得变量的指针,然后通过PyArg_Parse解析

pModule =PyImport_ImportModule("__main__");
pReturn = PyObject_GetAttrString(pModule, "a"); //可以获得全局变量
int size = PyDict_Size(pReturn);
PyObject *pNewAge = PyDict_GetItemString(pReturn, "Age");
int newAge;
PyArg_Parse(pNewAge, "i", &newAge);

对于元组的解析:

PyObject * pfun=PyObject_GetAttrString(pModule, "testdict"); //testdict:Python文件中的函数名
PyObject *pReturn = PyEval_CallObject(pfun, pArgs); //调用函数

5、调用Python函数

PyObject * pfun=PyObject_GetAttrString(pModule, "testdict"); //testdict:Python文件中的函数名
PyObject *pReturn = PyEval_CallObject(pfun, pArgs); //调用函数

6、设置函数让Python调用

首先定义c函数,然后声明方法列表,然后声明模块,然后增加这个模块,最后调用

static int numargs=1890;
static PyObject* emb_numargs(PyObject *self, PyObject *args) //C函数
{
  if(!PyArg_ParseTuple(args, ":numargs"))
    return NULL;
  return PyLong_FromLong(numargs);
}
static PyMethodDef EmbMethods[] = { //方法列表
  {"numargs", emb_numargs, METH_VARARGS,
   "Return the number of arguments received by the process."},
  {NULL, NULL, 0, NULL}
};
static PyModuleDef EmbModule = { //模块声明
  PyModuleDef_HEAD_INIT, "emb", NULL, -1, EmbMethods,
  NULL, NULL, NULL, NULL
};
static PyObject* PyInit_emb(void) //模块初始化函数
{
  return PyModule_Create(&EmbModule);
}
//增加模块:
PyImport_AppendInittab("emb", &PyInit_emb); //增加一个模块

到此这篇关于C语言中程序如何调用Python脚本的文章就介绍到这了,更多相关C语言调用Python脚本内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python调用C语言程序方法解析

    首先我们需要将编写好的c程序文件编译为动态库文件(后缀名为.so) 使用下面的命令: gcc 原文件名.c -shared -o 新文件名.so 然后在python程序中导入模块:from ctypes import * 在python中引入c动态库,并定义一个变量用来接收动态库: a=cdll.LoadLibrary("动态库文件路径") 然后就可以调用其中的函数了. a.函数名() 具体使用示例如下: //c语言代码 #include<stdio.h> void fun

  • Python调用C语言开发的共享库方法实例

    在helloworld工程中,编写了一个简单的两个数值相加的程序,编译成为共享库后,如何使用python对其进行调用呢? 使用ll命令列出当前目录下的共享库,其中共享库名为libhelloworld.so.0.0.0 复制代码 代码如下: ufo@ufo:~/helloworld/.libs$ ll 总用量 32 drwxr-xr-x 2 ufo ufo 4096  1月 29 14:54 ./ drwxr-xr-x 6 ufo ufo 4096  1月 29 16:08 ../ -rw-r--

  • Python调用C语言的实现

    Python中的ctypes模块可能是Python调用C方法中最简单的一种.ctypes模块提供了和C语言兼容的数据类型和函数来加载dll文件,因此在调用时不需对源文件做任何的修改.也正是如此奠定了这种方法的简单性. 示例如下 实现两数求和的C代码,保存为add.c //sample C file to add 2 numbers - int and floats #include <stdio.h> int add_int(int, int); float add_float(float,

  • Python实现的调用C语言函数功能简单实例

    本文实例讲述了Python实现的调用C语言函数功能.分享给大家供大家参考,具体如下: 实例参考python cookbook 中的15.1节中的例子P612页 先把 c文件编译成 so文件 gcc a.c -fpic -shared -o lib.so 通过上面编译成so文件 利用ctypes模块. from ctypes import cdll a=cdll.LoadLibrary("./lib.so") a.say() 能过上面代码测试通过. 更多关于Python相关内容感兴趣的读

  • C语言调用Python代码的方法

    问题 你想在C中安全的执行某个Python调用并返回结果给C. 例如,你想在C语言中使用某个Python函数作为一个回调. 解决方案 在C语言中调用Python非常简单,不过涉及到一些小窍门. 下面的C代码告诉你怎样安全的调用: #include <Python.h> /* Execute func(x,y) in the Python interpreter. The arguments and return result of the function must be Python flo

  • python 调用c语言函数的方法

    虽然python是万能的,但是对于某些特殊功能,需要c语言才能完成.这样,就需要用python来调用c的代码了 具体流程: c编写相关函数 ,编译成库 然后在python中加载这些库,指定调用函数. 这些函数可以char ,int, float, 还能返回指针. 以下示例: 通过python调用c函数,返回"hello,world 字符串" 新建c语言文件 hello.c touch hello.c #include <stdio.h> char *get_str() {

  • C语言中程序如何调用Python脚本

    有时候在写C语言程序的时候又想利用一下python强大的模块,于是C与python的混合编程便应运而生. 下面简单说说在C语言编译环境中调用python脚本文件的基础应用. 一.环境配置 以vs2017为例. 0x00 平台 首先你要知道你电脑上安装的python环境是64位还是32位,vs的编译平台需要与python环境一致. 比如我的python环境是64位,vs工程就要配置成x64. 右键点击你的解决方案,点击属性, 0x01 添加 包含目录 和 库目录 在属性窗口双击"VC++ Dire

  • Java程序中实现调用Python脚本的方法详解

    本文实例讲述了Java程序中实现调用Python脚本的方法.分享给大家供大家参考,具体如下: 在程序开发中,有时候需要Java程序中调用相关Python脚本,以下内容记录了先关步骤和可能出现问题的解决办法. 1.在Eclipse中新建Maven工程: 2.pom.xml文件中添加如下依赖包之后update maven工程: <dependency> <groupId>org.python</groupId> <artifactId>jython</ar

  • 教你在Excel中调用Python脚本实现数据自动化处理的方法

    目录 一.为什么将Python与Excel VBA集成? 二.为什么使用xlwings? 三.玩转xlwings 这次我们会介绍如何使用xlwings将Python和Excel两大数据工具进行集成,更便捷地处理日常工作. 说起Excel,那绝对是数据处理领域王者般的存在,尽管已经诞生三十多年了,现在全球仍有7.5亿忠实用户,而作为网红语言的Python,也仅仅只有700万的开发人员. Excel是全世界最流行的编程语言.对,你没看错,自从微软引入了LAMBDA定义函数后,Excel已经可以实现编

  • 详解C++调用Python脚本中的函数的实例代码

    1.环境配置 安装完python后,把python的include和lib拷贝到自己的工程目录下 然后在工程中包括进去 2.例子 先写一个python的测试脚本,如下 这个脚本里面定义了两个函数Hello()和_add().我的脚本的文件名叫mytest.py C++代码: #include "stdafx.h" #include <stdlib.h> #include <iostream> #include "include\Python.h&quo

  • 在node中如何调用python脚本

    目录 node调用python脚本 使用场景 1.准备运行环境,获取python路径 2.前端把命令字符串和python路径传给后端 3.服务端调用python脚本 nodejs调用python输出中文乱码 解决方法如下 node调用python脚本 使用场景 在某测试项目需要用到eload仪器为待测产品添加载荷,然后用dmm仪器测量电压,eload仪器与dmm仪器与电脑的连接都是usb接口,那么软件如何控制这两个usb连接的仪器呢. 通过搜索发现npm上有一个usb的依赖包,它可以查询到与电脑

  • C#调用Python脚本的简单示例

    IronPython是一种在 .NET及 Mono上的 Python实现,由微软的 Jim Hugunin所发起,是一个开源的项目,基于微软的 DLR引擎.IronPython的在CodePlex上的主页:http://ironpython.codeplex.com/ 使用场景: 如果你的小伙伴会写Python脚本,而且已经实现大部分项目的功能不需要再用C# 实现.现在缺少窗体,此时Python+C#的组合就可以完美的结局问题啦! 示例: 借由IronPython,就可以利用.NET执行存储在P

  • C#使用IronPython库调用Python脚本

    IronPython是一种在 .NET及 Mono上的 Python实现,由微软的 Jim Hugunin所发起,是一个开源的项目,基于微软的 DLR引擎. IronPython的主页: IronPython.net / github站点: IronLanguages/ironpython3: Implementation of Python 3.x for .NET Framework that is built on top of the Dynamic Language Runtime.

  • C# 如何调用python脚本

    目录 C#调用python脚本 方式一 方式二 方式三 方式四 方式五 C#调用python脚本 在平常工程项目开发过程中常常会涉及到机器学习.深度学习算法方面的开发任务,但是受限于程序设计语言本身的应用特点,该类智能算法的开发任务常常使用Python语言开发,所以在工程实践过程中常常会遇到多平台程序部署问题.本文总结了C#调用Python程序的各种方法,希望能够给各位读者提供一定的参考. 方式一 使用c#,nuget管理包上下载的ironPython安装包适用于python脚本中不包含第三方模

  • 在VS2017中用C#调用python脚本的实现

    情景是这样的:在C#中调用python脚本进行post请求,python脚本中使用了requests包. Python的开发环境我们有比较多的选择,pycharm.sublime text等等.但是作为.net平台的Python语言ironPython,可以和C#交互,让编程更活泛. ironPython本身其实就是一个python的开发环境,我的电脑上还装有python2.7和pycharm,开始的时候使用pycharm写的,本来的想法是用VS直接调用就可以了.但是后来才明白这三者的关系. p

  • 详解如何在VS2019和VScode中配置C++调用python接口

    why 看到这个标题有些人说了,为什么好好的C++你非要调用python?人家明明是两种语言呀! 但是在实际应用中,有时候会用到C/C++调用python来更简单地去完成一些功能,不然人家python为什么有一个文件夹叫include,里边全是.h文件呢? VScode中配置环境 首先是在VScode中为C++调用python接口配置环境,这里假设你已经配置好了c++编程环境! 1.配置step1 用快捷键Ctrl+Shift+X打开Extensions 商店,输入python,install:

随机推荐