欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言中程序如何調(diào)用Python腳本

 更新時間:2021年05月13日 10:34:09   作者:Em0s_Erit  
由于python有很多功能強(qiáng)大的開源庫,有時候在寫C語言程序的時候又想利用一下python強(qiáng)大的模塊,那么C語言中程序如何調(diào)用Python腳本,感興趣的小伙伴們可以參考一下

有時候在寫C語言程序的時候又想利用一下python強(qiáng)大的模塊,于是C與python的混合編程便應(yīng)運(yùn)而生。
下面簡單說說在C語言編譯環(huán)境中調(diào)用python腳本文件的基礎(chǔ)應(yīng)用。

一、環(huán)境配置

以vs2017為例。

0x00 平臺

首先你要知道你電腦上安裝的python環(huán)境是64位還是32位,vs的編譯平臺需要與python環(huán)境一致。
比如我的python環(huán)境是64位,vs工程就要配置成x64。

在這里插入圖片描述

右鍵點(diǎn)擊你的解決方案,點(diǎn)擊屬性,

在這里插入圖片描述

0x01 添加 包含目錄 和 庫目錄

在屬性窗口雙擊“VC++ Directories”(VC++目錄),把在Include Directories (包含目錄)和 Library Directories(庫目錄)下添加python安裝路徑下的include和ibs文件夾的路徑。

在這里插入圖片描述

0x02 添加依賴項(xiàng)

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

雙擊“l(fā)inker”(鏈接器)下的“Input”,添加python39_d.lib這個依賴項(xiàng)

在這里插入圖片描述

點(diǎn)擊確定則配置完成。

這樣在寫程序的時候添加Python.h頭文件就不會報錯,python39_d.lib里的API函數(shù)也就可以正常使用了。

二、案例

主要流程就是:

  • 初始化python
  • 導(dǎo)入py腳本(模塊)
  • 獲取模塊里的函數(shù)
  • 必要的C語言數(shù)據(jù)類型轉(zhuǎn)python的數(shù)據(jù)類型(傳參前)
  • 調(diào)用函數(shù)
  • 釋放python
#include<stdio.h>
#include <Python.h>
int main()
{
	PyObject *pName, *pModule, *pDict, *pFunc;
	PyObject *pArgs, *pValue;
	//待傳參數(shù)
	int time[6]={1,2,3,4,5,6};
	//初始化python
	Py_Initialize();
	// 檢查初始化是否成功  
	if (!Py_IsInitialized())
	{
		printf("初始化失敗\n");
		Py_Finalize();
	}
	//設(shè)置python模塊,搜尋位置,文件放在.c文件一起
	PyRun_SimpleString("import sys");
	PyRun_SimpleString("sys.path.append('./')");

	//獲取python文件名,導(dǎo)入模塊(我這里的py文件是graph.py) 
	pModule = PyImport_ImportModule("graph");
	if (!pModule) {
		printf("py文件導(dǎo)入失敗\n");
		Py_Finalize();
	}
	else {
		//直接獲取模塊中的函數(shù)
		pFunc = PyObject_GetAttrString(pModule, "create_graph");
		//驗(yàn)證函數(shù)是否獲取成功
		if (!pFunc) {
			printf("函數(shù)導(dǎo)入失敗\n");
			Py_Finalize();
		}

		//將c/c++類型數(shù)據(jù)轉(zhuǎn)換為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);
		
		//調(diào)用直接獲得的函數(shù),并傳遞參數(shù)
		pValue = PyObject_CallObject(pFunc, pArgs);

		//釋放python
		Py_Finalize();
		
		printf("success");
		return 0;
	}
}

順便給出我的graph.py的腳本,這是一個以參數(shù)的數(shù)值生成對應(yīng)的excel文件的腳本,這兩個源代碼是根據(jù)我的另一篇關(guān)于排序算法的博文改的案例。

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

def create_graph(a,b,c,d,e,f):
	# 創(chuàng)建一個excel
	workbook = xlsxwriter.Workbook("排序算法比較結(jié)果.xlsx")
	# 創(chuàng)建一個sheet
	worksheet = workbook.add_worksheet()
	# worksheet = workbook.add_worksheet("bug_analysis")

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

	# --------1、準(zhǔn)備數(shù)據(jù)并寫入excel---------------
	# 向excel中寫入數(shù)據(jù),建立圖標(biāo)時要用到
	headings = ["排序方法", "排序時間"]
	data = [["簡單選擇排序", "直接插入排序", "冒泡排序", "快速排序", "兩路合并排序", "堆排序"],[a,b,c,d,e,f]]
	
	# 寫入表頭
	worksheet.write_row('A1', headings, bold)
 
	# 寫入數(shù)據(jù)
	worksheet.write_column('A2', data[0])
	worksheet.write_column('B2', data[1])
 
	# --------2、生成圖表并插入到excel---------------
	# 創(chuàng)建一個柱狀圖(column chart)
	chart_col = workbook.add_chart({'type': 'column'})
 
	# 配置第一個系列數(shù)據(jù)
	chart_col.add_series({'name': '=Sheet1!$B$1','categories': '=Sheet1!$A$2:$A$7','values':   '=Sheet1!$B$2:$B$7','line': {'color': 'red'},})
	# 這里的sheet1是默認(rèn)的值,因?yàn)槲覀冊谛陆╯heet時沒有指定sheet名
	# 如果我們新建sheet時設(shè)置了sheet名,這里就要設(shè)置成相應(yīng)的值
 
	# 設(shè)置圖表的title 和 x,y軸信息
	chart_col.set_title({'name': "排序算法結(jié)果"})
	chart_col.set_x_axis({'name': "排序方法"})
	chart_col.set_y_axis({'name':  "花費(fèi)時間(ms)"})
 
	# 設(shè)置圖表的風(fēng)格
	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、運(yùn)行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的變量賦值

對于數(shù)值,使用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}

對于其他數(shù)據(jù)結(jié)構(gòu),使用相應(yīng)的函數(shù)設(shè)置,例如:

PyObject *pArgs = PyTuple_New(1);
PyObject *pDict = PyDict_New();  //創(chuàng)建字典類型變量 
PyDict_SetItemString(pDict, "Name", Py_BuildValue("s", "YQC")); //往字典類型變量中填充數(shù)據(jù) 
PyDict_SetItemString(pDict, "Age", Py_BuildValue("i", 25)); //往字典類型變量中填充數(shù)據(jù) 
PyTuple_SetItem(pArgs, 0, pDict);//0---序號 將字典類型變量添加到參數(shù)元組中 

構(gòu)造好對象以后,通過PyObject_SetAttrString來設(shè)置進(jìn)入Python中:

PyObject *ps=PyUnicode_DecodeUTF8(val,strlen(val),"ignore"); //構(gòu)造了一個對象
PyObject_SetAttrString(p_main_Module,key,ps); //設(shè)置

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文件中的函數(shù)名
PyObject *pReturn = PyEval_CallObject(pfun, pArgs); //調(diào)用函數(shù)

5、調(diào)用Python函數(shù)

PyObject * pfun=PyObject_GetAttrString(pModule, "testdict"); //testdict:Python文件中的函數(shù)名
PyObject *pReturn = PyEval_CallObject(pfun, pArgs); //調(diào)用函數(shù)

6、設(shè)置函數(shù)讓Python調(diào)用

首先定義c函數(shù),然后聲明方法列表,然后聲明模塊,然后增加這個模塊,最后調(diào)用

static int numargs=1890;
static PyObject* emb_numargs(PyObject *self, PyObject *args) //C函數(shù)
{
  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) //模塊初始化函數(shù)
{
  return PyModule_Create(&EmbModule);
}
//增加模塊:
PyImport_AppendInittab("emb", &PyInit_emb); //增加一個模塊

到此這篇關(guān)于C語言中程序如何調(diào)用Python腳本的文章就介紹到這了,更多相關(guān)C語言調(diào)用Python腳本內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論