C++調用python(執行py文件)的全過程
1、首先要配好vs開發工程
註意版本;我這使用32位的python那麼我vs工程這邊也選擇32位的編譯環境去配置
註意點;需要將python安裝目錄的一些文件拷過來作為vs工程使用。
2、C++調用Python結果
py代碼
這裡引用瞭cdll庫也需要放置到運行目錄,py文件也是需要放置到運行目錄(也就是exe生成所在目錄)
import os import time from ctypes import * def testDLL(): pDll = CDLL("./pythonTestCDll.dll") pstr = create_string_buffer(1024, '\0') # 創建字符串緩沖區 # 對輸入輸出參數進行聲明 GetAndSetString = pDll.GetAndSetString GetAndSetString.restype = c_char_p GetAndSetString.argtypes = [c_char_p] pchar = GetAndSetString(pstr) szbuffer = c_char_p(pchar) # 強制轉換為c_char_p類型,取其value值 print(pstr.value) print(szbuffer.value) def Start(): testDLL()
C++代碼
#include <iostream> #include "Python.h" using namespace std; void Hello(); void Add(); void Start(); void Hello1() { cout << "\n調用Test001.py中的Add函數..." << endl; } int main(int argc, char* argv[]) { /*cout << "調用Test001.py中的Hello函數..." << endl; Hello(); cout << "\n調用Test001.py中的Add函數..." << endl; Add();*/ cout << "調用testMultiprocessingDll.py中的Start函數..." << endl; Start(); getchar(); return 0; } void Start() { Py_Initialize();//調用Py_Initialize()進行初始化 if (!Py_IsInitialized()) { printf("Python envirment initialized fale!"); return; } PyObject * pModule = NULL; PyObject * pFunc = NULL; PyRun_SimpleString("import sys"); PyRun_SimpleString("sys.path.append('D:/code/pythonTestCDll/CdoPython/Release/DLLs')"); //PyRun_SimpleString("print(\"sdasd\")"); pModule = PyImport_ImportModule("testMultiprocessingDll");//調用的Python文件名 py文件放置exe同級 if (pModule == NULL) { PyErr_Print(); cout << "PyImport_ImportModule Fail!" << endl; return; } pFunc = PyObject_GetAttrString(pModule, "__main__");//調用的函數名 PyEval_CallObject(pFunc, NULL);//調用函數,NULL表示參數為空 Py_Finalize();//調用Py_Finalize,和Py_Initialize相對應的. } void Hello() { Py_Initialize();//調用Py_Initialize()進行初始化 if (!Py_IsInitialized()) { printf("Python envirment initialized fale!"); return ; } PyObject * pModule = NULL; PyObject * pFunc = NULL; PyRun_SimpleString("print(\"sdasd\")" ); pModule = PyImport_ImportModule("Test001");//調用的Python文件名 py文件放置exe同級 if (pModule == NULL) { PyErr_Print(); cout << "PyImport_ImportModule Fail!" << endl; return; } pFunc = PyObject_GetAttrString(pModule, "Hello");//調用的函數名 PyEval_CallObject(pFunc, NULL);//調用函數,NULL表示參數為空 Py_Finalize();//調用Py_Finalize,和Py_Initialize相對應的. } //調用Add函數,傳兩個int型參數 void Add() { Py_Initialize(); PyObject * pModule = NULL; PyObject * pFunc = NULL; pModule = PyImport_ImportModule("Test001");//Test001:Python文件名 pFunc = PyObject_GetAttrString(pModule, "Add");//Add:Python文件中的函數名 //創建參數: PyObject *pArgs = PyTuple_New(2);//函數調用的參數傳遞均是以元組的形式打包的,2表示參數個數 PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", 6));//0--序號,i表示創建int型變量 PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", 8));//1--序號 //返回值 PyObject *pReturn = NULL; pReturn = PyEval_CallObject(pFunc, pArgs);//調用函數 //將返回值轉換為int類型 int result; PyArg_Parse(pReturn, "i", &result);//i表示轉換成int型變量 cout << "6 + 8 = " << result << endl; Py_Finalize(); }
3、報錯:ValueError: source code string cannot contain null bytes
參考鏈接:
https://blog.csdn.net/LaoYuanPython/article/details/97623504
https://blog.csdn.net/zichen_ziqi/article/details/79068656
4、C++調用python文件中import時報錯
參考鏈接://www.jb51.net/article/233313.htm
5、C++多線程調用Python多進程multiprocessing時發現不支持
C++多線程調用Python多進程
C++、Java等編程想提高效率,很容易想到的就是使用多線程,而在Python中,由於使用瞭GIL,使得多線程效率非但沒有將性能線性提升,反而可能會比單線程效率還低。在進程間不需要怎麼通信的時候,multiprocessing就很好用瞭。但是翻遍瞭C/Python API沒找到C語言調用Python多進程的方法。而目前的項目卻恰好希望能用C++調用Python多進程。嘗試瞭好多C/Python API都沒有一個穩定可靠的方案,今天終於試出來瞭一種可行的方案!
該方案的前提是進程間不需要通信!
方法很簡單,使用linux的shell啟動python進程!
C++部分思路:
1. 使用c++創建多個線程,根據自己的邏輯寫好入口函數和輸入參數
2. 在線程入口函數中,將想要執行的linux命令封裝成一個字符串如s=”python test.py a b c”,其中a,b,c是test.py的系統參數,完成瞭C++向python的傳參,當然隻是一些簡單的類型
3. 定義好python的控制臺上的輸出,使用popen()執行s的命令並建立管道
4. 獲取控制臺的輸出,並按照已定義好的規則來判斷返回信息
5. 根據返回信息,執行對應的操作
Python部分思路:
基本不用修改,隻是把普通的函數傳參改為獲取系統參數,將函數返回值改為控制臺輸出,當然返回值類型受限
該方案成功解決瞭C++多線程調用Python多進程的問題,提升瞭效率,缺點是進程間不能通信,隻能相互傳遞比較簡單的參數!
總結
到此這篇關於C++調用python(執行py文件)的文章就介紹到這瞭,更多相關C++調執行py文件內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 膠水語言Python與C/C++的相互調用的實現
- 詳解如何在VS2019和VScode中配置C++調用python接口
- 如何在C++中調用Python
- Python與C/C++的相互調用案例
- C語言代碼實現簡單2048遊戲