最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

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

python文件test.py

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

新建一個VS控制臺項目

main.cpp所有的源碼如下:

#include <stdio.h>
#include <python.h>
#include <windows.h>
void main()
{
    Py_Initialize(); // 初始化python虛擬機
    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個int型參數(shù)
    int ok = -1;
    int retok = PyArg_Parse(pyRet, "i", &ok); // 從返回值從取出int型返回值
    Py_Finalize();
    system("pause");
}

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

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

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

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

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

下面幾個基礎類型的返回值解析

#python
#返回一個參數(shù)
def returnInt(a,b):
    return a+b
#返回兩個相同類型的參數(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()
#返回兩個不同類型的參數(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ù)實際類型進行解析
	PyObject* pReturn = PyObject_CallObject(pFunc, pArgs);
	//當不需要傳參時,可以將參數(shù)位置為空
	PyObject* pReturn = PyObject_CallObject(pFunc,NULL);

PyObject為結構體,參數(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 兩個不同類型的參數(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;
	}
//返回單獨一個變量
	//構建輸入
	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;

//返回多個變量
	//循環(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;
//解析二維矩陣
	//獲得序列長度,即行數(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 }
		//獲得當前行的數(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手冊,接口的使用示例等

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

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

總結

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

相關文章

  • C++非遞歸隊列實現(xiàn)二叉樹的廣度優(yōu)先遍歷

    C++非遞歸隊列實現(xiàn)二叉樹的廣度優(yōu)先遍歷

    這篇文章主要介紹了C++非遞歸隊列實現(xiàn)二叉樹的廣度優(yōu)先遍歷,實例分析了遍歷二叉樹相關算法技巧,并附帶了兩個相關算法實例,需要的朋友可以參考下
    2015-07-07
  • C++使用泛型導致的膨脹問題

    C++使用泛型導致的膨脹問題

    這篇文章主要介紹了C++使用泛型導致的膨脹,智能家居主機的嵌入式平臺上使用C++進行開發(fā)。FLASH存儲空間有限,這是必須要考慮的因素,一定要重視,下面我們一起進入文章看看詳細內(nèi)容
    2021-11-11
  • 淺談Qt信號槽與事件循環(huán)的關系

    淺談Qt信號槽與事件循環(huán)的關系

    本文主要介紹了Qt信號槽與事件循環(huán)的關系,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-08-08
  • QT實現(xiàn)QML側(cè)邊導航欄的最簡方法

    QT實現(xiàn)QML側(cè)邊導航欄的最簡方法

    本文主要介紹了QT實現(xiàn)QML側(cè)邊導航欄的最簡方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-06-06
  • 深入分析C++派生類中的保護成員繼承

    深入分析C++派生類中的保護成員繼承

    這篇文章主要介紹了C++派生類中的保護成員繼承,深入對C++面向?qū)ο缶幊痰睦^承機制進行了解析,需要的朋友可以參考下
    2015-09-09
  • 深入分析Linux下如何對C語言進行編程

    深入分析Linux下如何對C語言進行編程

    本篇文章介紹了,如何在Linux下對C語言進行編程的詳細概述。需要的朋友參考下
    2013-05-05
  • C++中LibCurl庫使用流程及配置詳解

    C++中LibCurl庫使用流程及配置詳解

    libcurl是一個跨平臺的開源網(wǎng)絡傳輸庫,它支持許多協(xié)議,包括HTTP、HTTPS、FTP、FTPS以及許多其他協(xié)議和文件傳輸方式,本文給大家詳細介紹了C++中LibCurl庫使用流程及配置,需要的朋友可以參考下
    2024-02-02
  • C++ 線程互斥鎖 lock_guard的基本用法

    C++ 線程互斥鎖 lock_guard的基本用法

    std::lock_guard是C++11提供的RAII風格互斥鎖封裝類,自動管理互斥鎖的加鎖/解鎖,避免忘記解鎖和異常導致的鎖無法釋放等問題,它通過構造時加鎖、析構時解鎖的機制,簡化了多線程編程中的鎖管理,本文介紹C++線程互斥鎖lock_guard的基本用法,感興趣的朋友一起看看吧
    2026-01-01
  • C語言深入講解函數(shù)的使用

    C語言深入講解函數(shù)的使用

    各位小伙伴們,今天YU同學給大家?guī)淼氖桥c函數(shù)相關的知識,本篇將會帶著大家初步認識和調(diào)用函數(shù)來解決一些簡單的問題
    2022-04-04
  • C++11 智能指針之shared_ptr代碼詳解

    C++11 智能指針之shared_ptr代碼詳解

    這篇文章主要介紹了 C++11 智能指針之shared_ptr的相關知識,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06

最新評論

洱源县| 浠水县| 勐海县| 鹿邑县| 紫金县| 枣庄市| 明溪县| 湾仔区| 大竹县| 缙云县| 景谷| 平塘县| 凤凰县| 巴林右旗| 通化县| 遂宁市| 夹江县| 彰化市| 凤城市| 修水县| 白沙| 和政县| 富锦市| 弋阳县| 浙江省| 黑河市| 肃宁县| 桦南县| 福海县| 五寨县| 景洪市| 禹城市| 固阳县| 梁平县| 凤阳县| 秦安县| 陇西县| 张家港市| 洱源县| 惠安县| 内江市|