亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++如何調(diào)用python并取返回值

 更新時(shí)間:2024年03月01日 10:53:01   作者:玖五二七  
這篇文章主要介紹了C++如何調(diào)用python并取返回值問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

C++調(diào)用python并取返回值

前面介紹了用python調(diào)用C++時(shí)用swig工具,現(xiàn)在簡(jiǎn)單介紹一下C++調(diào)用python并取返回值的過(guò)程

python文件test.py

class tester:
    def add(self, a, b):
        return a + b

新建一個(gè)VS控制臺(tái)項(xiàng)目

main.cpp所有的源碼如下:

#include <stdio.h>
#include <python.h>
#include <windows.h>
void main()
{
    Py_Initialize(); // 初始化python虛擬機(jī)
    PyObject* pyMod  = PyImport_ImportModule("test"); //  加載test.py文件
    PyObject* pyDict = PyModule_GetDict(pyMod); //  獲取test模塊中的字典
    PyObject* pyCls = PyDict_GetItemString(pyDict, "tester"); // 從字典中查找tester類
    PyObject* PyIns = PyInstance_New(pyCls, NULL, NULL); // 創(chuàng)建tester類
    PyObject* pyRet = PyObject_CallMethod(pyIns, "add", "ii", 5, 6); // 調(diào)用tester.add方法,傳入2個(gè)int型參數(shù)
    int ok = -1;
    int retok = PyArg_Parse(pyRet, "i", &ok); // 從返回值從取出int型返回值
    Py_Finalize();
    system("pause");
}

整個(gè)過(guò)程最重要的是  PyBoject_CallMethod,傳入的參數(shù)類型一定不能搞錯(cuò)。

還有取返回值的時(shí)候PyArg_Parse取單個(gè)返回值,要是取多個(gè)的可以用PyArg_ParseTuple,要取的類型也必須完全匹配。

c++調(diào)用python時(shí)參數(shù)傳遞和返回值解析

通過(guò)python接口在cpp中調(diào)用python函數(shù)時(shí),構(gòu)建傳參和解析返回值都會(huì)用到python內(nèi)的變量類型和c++的變量類型之間的轉(zhuǎn)換。

返回值是numpy等復(fù)雜結(jié)構(gòu)的數(shù)據(jù)時(shí),可以通過(guò)先轉(zhuǎn)換為list等類型再返回,或者單獨(dú)構(gòu)建一個(gè)函數(shù),獲取numpy內(nèi)某個(gè)位置的變量的函數(shù)。

下面幾個(gè)基礎(chǔ)類型的返回值解析

#python
#返回一個(gè)參數(shù)
def returnInt(a,b):
    return a+b
#返回兩個(gè)相同類型的參數(shù)
def returnTwoInt():
    return 1,2
#返回字符串
def returnString():
    srt = 'hello world'
    return srt
#返回list
def returnList():
	para = [1, 2, 3, 4]
    return 1,para.tolist()
#返回兩個(gè)不同類型的參數(shù)
def returnTwo():
	para = [1, 2, 3, 4]
    return 1,para.tolist()
#返回矩陣
def returnMat():
    img = cv2.imread('test1.bmp',cv2.IMREAD_GRAYSCALE)
    return img
	//調(diào)用python函數(shù),返回的數(shù)據(jù)統(tǒng)一為PyObject類型,需要根據(jù)實(shí)際類型進(jìn)行解析
	PyObject* pReturn = PyObject_CallObject(pFunc, pArgs);
	//當(dāng)不需要傳參時(shí),可以將參數(shù)位置為空
	PyObject* pReturn = PyObject_CallObject(pFunc,NULL);

PyObject為結(jié)構(gòu)體,參數(shù)ob_type->tp_name 為數(shù)據(jù)的類型

//不同類型參數(shù)傳遞
	PyObject* p = PyTuple_New(4);
	for (int i = 0; i < 4; i++)
		PyTuple_SetItem(p, i, Py_BuildValue("i", i));
	PyObject* pArgs = PyTuple_New(2);
	PyTuple_SetItem(pArgs, 0,Py_BuildValue ("i",1));
	PyTuple_SetItem(pArgs, 0,Py_BuildValue ("O",p));
	
//返回為list
	double temp;
	int i_size = PyList_Size(pReturn); 
	for (int i = 0; i < i_size; ++i)
	{
		PyArg_Parse(PyList_GetItem(pReturn, i), "d", &temp);
		std::cout << "return result is " << (temp) << std::endl;
	}
//返回為 int 和 list 兩個(gè)不同類型的參數(shù)
	PyArg_Parse(PyTuple_GetItem(pReturn, 0), "d", &temp);
	std::cout << "temp is " << (temp) << std::endl;
	PyObject* pReturnlist;
	PyArg_Parse(PyTuple_GetItem(pReturn, 1), "O", &pReturnlist);
	i_size = PyList_Size(pReturnli); 
	for (int i = 0; i < i_size; ++i)
	{
		PyArg_Parse(PyList_GetItem(pReturnli, i), "d", &temp);
		std::cout << "return result is " << (temp) << std::endl;
	}
//返回單獨(dú)一個(gè)變量
	//構(gòu)建輸入
	PyObject* pArgs = PyTuple_New(2);
	PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", 1));
	PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", 1));
	PyObject* pReturn2 = PyObject_CallObject(pFunc, pArgs);
	//解析
	int nResult1;	//解析為int
	PyArg_Parse(pReturn2, "i", &nResult1);
	std::cout << "add=" << nResult1 << std::endl;
	double nResultd;	//解析為double
	PyArg_Parse(pReturn2, "d", &nResultd);
	std::cout << "add=" << nResultd << std::endl;
//返回字符串
	//解析方法1:
	PyObject* repr = PyObject_Repr(pReturn);
	PyObject* str = PyUnicode_AsEncodedString(repr, "utf-8", "strict");
	char* result = PyBytes_AsString(str);
	std::cout << result << std::endl;
	//解析方法2:
	char* pstr = NULL;
	PyArg_Parse(pReturn, "s", &pstr);
	std::cout << pstr << std::endl;

//返回多個(gè)變量
	//循環(huán)解析
	int nResult;
	i_size = PyTuple_Size(pReturn); 
	for (int i = 0; i < i_size; ++i)
	{
		PyArg_Parse(PyTuple_GetItem(pReturn, i), "i", &nResult);
		std::cout << "return result is " << (nResult) << std::endl;
	}
	//直接解析
	int nResult1;
	int nResult2;
	PyArg_ParseTuple(pReturn,"i|i", &nResult1, &nResult2);   
	std::cout << "return  " << nResult5<< ' ' << nResult6 << std::endl;
//解析二維矩陣
	//獲得序列長(zhǎng)度,即行數(shù)
	Py_ssize_t rsize = PyObject_Size(pReturn);
	std::cout << rsize << std::endl;
	//轉(zhuǎn)換到迭代器,用于提取數(shù)據(jù)
	PyObject* iter = PyObject_GetIter(pReturn5);
	while (true)
	{
		//獲取矩陣的第一行
		PyObject* next = PyIter_Next(iter);
		if (!next) { // nothing left in the iterator
			break;
		}
		if (!PyList_Check(next))
		{ // error, we were expecting a list value }
		//獲得當(dāng)前行的數(shù)據(jù)數(shù)量
		Py_ssize_t foosize = PyObject_Size(next);
		std::cout << foosize << std::endl;
		//轉(zhuǎn)換到迭代器,用于獲取數(shù)據(jù)
		PyObject* iter2 = PyObject_GetIter(next);
		while (true)
		{
			PyObject* next2 = PyIter_Next(iter2);
			if (!next2)
				break;
			if (!PyFloat_Check(next2))
			 {// error, we were expecting a floating point value}
			double foo = PyFloat_AsDouble(next2);
			std::cout << foo << " ";
		}
		std::cout << std::endl;
	}

python手冊(cè),接口的使用示例等

https://docs.python.org/3/

	//解析常用字段:
	// b <=>char 0-255的那個(gè)char
	// c <=>char 單個(gè)字符
	// h <=>short int
	// l <=>long int
	// f <=>float
	// d <=>double
	// s <=>char*
	// O <=> PyObject 

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • C++詳細(xì)講解圖的遍歷

    C++詳細(xì)講解圖的遍歷

    圖的遍歷是指,從給定圖中任意指定的頂點(diǎn)(稱為初始點(diǎn))出發(fā),按照某種搜索方法沿著圖的邊訪問(wèn)圖中的所有頂點(diǎn),使每個(gè)頂點(diǎn)僅被訪問(wèn)一次,這個(gè)過(guò)程稱為圖的遍歷
    2022-05-05
  • 深入linux下遍歷目錄樹的方法總結(jié)分析

    深入linux下遍歷目錄樹的方法總結(jié)分析

    本篇文章是對(duì)linux下遍歷目錄樹的方法進(jìn)行了詳細(xì)的總結(jié)與分析,需要的朋友參考下
    2013-05-05
  • C語(yǔ)言非遞歸算法解決快速排序與歸并排序產(chǎn)生的棧溢出

    C語(yǔ)言非遞歸算法解決快速排序與歸并排序產(chǎn)生的棧溢出

    上期我們講完了排序算法下,不知道小伙伴們有沒(méi)有發(fā)現(xiàn)一個(gè)問(wèn)題,快速排序和歸并排序我們都是用遞歸來(lái)實(shí)現(xiàn)的,可能有小伙伴會(huì)問(wèn),如果說(shuō)數(shù)據(jù)量很多話,棧區(qū)空間會(huì)不會(huì)不夠用呢?這期我們就來(lái)解決使用遞歸實(shí)現(xiàn)的排序?qū)е聴R绯鋈绾谓鉀Q
    2022-04-04
  • 聊聊c++數(shù)組名稱和sizeof的問(wèn)題

    聊聊c++數(shù)組名稱和sizeof的問(wèn)題

    這篇文章主要介紹了c++數(shù)組名稱和sizeof,介紹了一維數(shù)組名稱的用途及二維數(shù)組數(shù)組名,通過(guò)示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-01-01
  • 詳解進(jìn)程同步與互斥機(jī)制

    詳解進(jìn)程同步與互斥機(jī)制

    進(jìn)程同步是一個(gè)操作系統(tǒng)級(jí)別的概念,是在多道程序的環(huán)境下,存在著不同的制約關(guān)系,為了協(xié)調(diào)這種互相制約的關(guān)系,實(shí)現(xiàn)資源共享和進(jìn)程協(xié)作,從而避免進(jìn)程之間的沖突,引入了進(jìn)程同步
    2021-06-06
  • C語(yǔ)言實(shí)現(xiàn)推箱子游戲的地圖編輯器

    C語(yǔ)言實(shí)現(xiàn)推箱子游戲的地圖編輯器

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)推箱子游戲的地圖編輯器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • C++友元(Friend)用法實(shí)例簡(jiǎn)介

    C++友元(Friend)用法實(shí)例簡(jiǎn)介

    這篇文章主要介紹了C++友元(Friend)用法,對(duì)于C++的學(xué)習(xí)來(lái)說(shuō)有很好的參考價(jià)值,需要的朋友可以參考下
    2014-08-08
  • c++并查集優(yōu)化(基于size和rank)

    c++并查集優(yōu)化(基于size和rank)

    這篇文章主要介紹了c++并查集優(yōu)化(基于size和rank),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • CMake中使用vcpkg的實(shí)現(xiàn)

    CMake中使用vcpkg的實(shí)現(xiàn)

    本文主要介紹了CMake中使用vcpkg的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • C++日期類(Date)實(shí)現(xiàn)的示例代碼

    C++日期類(Date)實(shí)現(xiàn)的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用C++語(yǔ)言實(shí)現(xiàn)日期類(Date),可以實(shí)現(xiàn)確定某年某月有多少天、打印日期等功能,感興趣的可以了解一下
    2022-07-07

最新評(píng)論