




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第如何在C++中調(diào)用Python為了使用Python.h這個(gè)擴(kuò)展項(xiàng),我們需要安裝一個(gè)python*-dev而不是python*,這兩者略有區(qū)別,下面的案例展示的是在Ubuntu20.04下安裝python3.9-dev的方法:
dechin@ubuntu2004:~/projects/gitlab/dechin/$sudoaptinstallpython3.9-dev
正在讀取軟件包列表...完成
正在分析軟件包的依賴關(guān)系樹
正在讀取狀態(tài)信息...完成
下列軟件包是自動(dòng)安裝的并且現(xiàn)在不需要了:
chromium-codecs-ffmpeg-extragstreamer1.0-vaapi
libgstreamer-plugins-bad1.0-0linux-headers-5.8.0-43-generic
linux-hwe-5.8-headers-5.8.0-43linux-image-5.8.0-43-generic
linux-modules-5.8.0-43-genericlinux-modules-extra-5.8.0-43-generic
使用'sudoaptautoremove'來卸載它(它們)。
將會(huì)同時(shí)安裝下列軟件:
libexpat1-devlibpython3.9libpython3.9-devzlib1g-dev
下列【新】軟件包將被安裝:
libexpat1-devlibpython3.9libpython3.9-devpython3.9-devzlib1g-dev
升級(jí)了0個(gè)軟件包,新安裝了5個(gè)軟件包,要卸載0個(gè)軟件包,有30個(gè)軟件包未被升級(jí)。
需要下載6,613kB的歸檔。
解壓縮后會(huì)消耗28.7MB的額外空間。
您希望繼續(xù)執(zhí)行嗎?[Y/n]Y
獲取:1/ubuntufocal/mainamd64libexpat1-devamd642.2.9-1build1[116kB]
獲取:2/ubuntufocal-updates/universeamd64libpython3.9amd643.9.0-5~20.04[1,710kB]
獲取:3/ubuntufocal-updates/universeamd64libpython3.9-devamd643.9.0-5~20.04[4,119kB]
獲取:4/ubuntufocal-updates/mainamd64zlib1g-devamd641:1.2.11.dfsg-2ubuntu1.2[155kB]
獲取:5/ubuntufocal-updates/universeamd64python3.9-devamd643.9.0-5~20.04[512kB]
已下載6,613kB,耗時(shí)4秒(1,594kB/s)
正在選中未選擇的軟件包libexpat1-dev:amd64。
(正在讀取數(shù)據(jù)庫...系統(tǒng)當(dāng)前共安裝有269544個(gè)文件和目錄。)
準(zhǔn)備解壓.../libexpat1-dev_2.2.9-1build1_amd64.deb...
正在解壓libexpat1-dev:amd64(2.2.9-1build1)...
正在選中未選擇的軟件包libpython3.9:amd64。
準(zhǔn)備解壓.../libpython3.9_3.9.0-5~20.04_amd64.deb...
正在解壓libpython3.9:amd64(3.9.0-5~20.04)...
正在選中未選擇的軟件包libpython3.9-dev:amd64。
準(zhǔn)備解壓.../libpython3.9-dev_3.9.0-5~20.04_amd64.deb...
正在解壓libpython3.9-dev:amd64(3.9.0-5~20.04)...
正在選中未選擇的軟件包zlib1g-dev:amd64。
準(zhǔn)備解壓.../zlib1g-dev_1%3a1.2.11.dfsg-2ubuntu1.2_amd64.deb...
正在解壓zlib1g-dev:amd64(1:1.2.11.dfsg-2ubuntu1.2)...
正在選中未選擇的軟件包python3.9-dev。
準(zhǔn)備解壓.../python3.9-dev_3.9.0-5~20.04_amd64.deb...
正在解壓python3.9-dev(3.9.0-5~20.04)...
正在設(shè)置libpython3.9:amd64(3.9.0-5~20.04)...
正在設(shè)置libexpat1-dev:amd64(2.2.9-1build1)...
正在設(shè)置zlib1g-dev:amd64(1:1.2.11.dfsg-2ubuntu1.2)...
正在設(shè)置libpython3.9-dev:amd64(3.9.0-5~20.04)...
正在設(shè)置python3.9-dev(3.9.0-5~20.04)...
正在處理用于man-db(2.9.1-1)的觸發(fā)器...
正在處理用于libc-bin(2.31-0ubuntu9.2)的觸發(fā)器...
安裝完成后,如果在當(dāng)前命令行下運(yùn)行python3.9,是可以看到一個(gè)python專屬的命令行界面的,可以通過exit()退出。但是我們這里側(cè)重的是跟C++的配合工作,因此我們更加關(guān)注lib和include目錄下是否有生成相關(guān)的目錄,可以執(zhí)行如下指令進(jìn)行查看:
dechin@ubuntu2004:~/projects/gitlab/dechin/$ll/usr/lib/|greppython
drwxr-xr-x26rootroot204805月716:27python2.7/
drwxr-xr-x3rootroot40962月1002:47python3/
drwxr-xr-x30rootroot204805月716:30python3.8/
drwxr-xr-x31rootroot122885月2016:31python3.9/
這里我們看到有一個(gè)3.9的版本,也就是我們剛才安裝的版本,再看看include下的目錄:
dechin@ubuntu2004:~/projects/gitlab/dechin/$ll/usr/include/|greppython
drwxr-xr-x2rootroot40965月716:31python3.8/
drwxr-xr-x4rootroot40965月2016:31python3.9/
這里我們就可以看到一些區(qū)別了,有一些版本的python不一定會(huì)有這兩個(gè)目錄,但是只有具備了這兩個(gè)目錄,才能夠被C++調(diào)用。
VSCode配置
這里我們使用的IDE是VSCode,但是上述提到的幾個(gè)路徑,在VSCode中默認(rèn)是不被包含的,因此在代碼編輯的過程中在includePython.h這一步就會(huì)報(bào)錯(cuò)了。這一章節(jié)的目的主要是解決IDE中的報(bào)錯(cuò)問題,還不是最終運(yùn)行中出現(xiàn)的問題,因?yàn)檫\(yùn)行時(shí)我是通過命令行執(zhí)行g(shù)++來運(yùn)行的,而不是直接用IDE來跑。首先在VSCode界面上按順序同時(shí)按?。篶trl+shift+P,在彈出的窗口中輸入C/C++EditConfigurations(JSON)查找相關(guān)JSON配置文件,在列表中點(diǎn)擊后會(huì)自動(dòng)在VSCode中打開這個(gè)配置文件:
"configurations":[
"name":"Linux",
"includePath":[
"${workspaceFolder}/**"
"defines":[],
"compilerPath":"/usr/bin/gcc",
"cStandard":"gnu17",
"cppStandard":"c++11",
"intelliSenseMode":"linux-gcc-x64"
"version":4
}
我們所需要做的工作就是,在這個(gè)includePath中把相關(guān)的路徑都加上,比如我這邊添加的路徑是以下3個(gè):
"configurations":[
"name":"Linux",
"includePath":[
"${workspaceFolder}/**",
"/usr/include/python3.9/",
"/usr/lib/python3.9/",
"/usr/include/python3.9/cpython/"
"defines":[],
"compilerPath":"/usr/bin/gcc",
"cStandard":"gnu17",
"cppStandard":"c++11",
"intelliSenseMode":"linux-gcc-x64"
"version":4
}
添加后,includePython.h就不會(huì)顯示報(bào)錯(cuò)了。
HelloWorld測(cè)試
行業(yè)潛規(guī)則,我們先用C++來調(diào)用一個(gè)Python的打印函數(shù),輸出HelloWorld試試:
//cp.cpp
#includePython.h
intmain(intargc,char*argv[]){
Py_Initialize();
PyRun_SimpleString("print('helloworld')\n");
Py_Finalize();
return0;
}
這里需要注意的是一個(gè)運(yùn)行方式,我們是用g++來進(jìn)行編譯的,但是g++默認(rèn)是找不到我們剛才在IDE中所設(shè)定的幾個(gè)includePath的,因此需要我們手動(dòng)在編譯的時(shí)候加上幾個(gè)參數(shù)。這些參數(shù)其實(shí)也可以運(yùn)行python3.9-config去一個(gè)一個(gè)查看,這里我們直接推薦一種可以運(yùn)行成功的參數(shù),其中最重要的是-I和-l這兩個(gè)路徑一定要包含:
dechin@ubuntu2004:~/projects/gitlab/dechin/$g++-ocpycp.cpp-lm-std=c++11-I/usr/include/python3.9/-lpython3.9
dechin@ubuntu2004:~/projects/gitlab/dechin/$ll
總用量4697388
drwxrwxr-x2dechindechin40965月2017:10./
drwxrwxr-x8dechindechin40965月1915:32../
-rw-rw-r--1dechindechin1525月2017:04cp.cpp
-rwxrwxr-x1dechindechin167765月2017:10cpy*
運(yùn)行完成后,就會(huì)在當(dāng)前目錄下生成一個(gè)剛才指定的名字cpy的一個(gè)可執(zhí)行文件,如果是windows系統(tǒng),則會(huì)生成一個(gè)cpy.exe的文件。讓我們執(zhí)行這個(gè)文件:
dechin@ubuntu2004:~/projects/gitlab/dechin/$./cpy
helloworld
成功打印HelloWorld,又離成功更近了一步。
調(diào)用Python函數(shù)string.split()
在C++中如果我們想分割一個(gè)字符串,雖然說也是可以實(shí)現(xiàn)的,但是應(yīng)該沒有比Python中執(zhí)行一個(gè)string.split()更加方便快捷的方案了,因此我們測(cè)試一個(gè)用C++調(diào)用Python的split函數(shù)的功能。
第一次嘗試
一開始我們是寫了這樣一個(gè)簡(jiǎn)單的案例,用PyImport_ImportModule方法去調(diào)用pysplit這個(gè)python模塊:
//cp.cpp
#includePython.h
#includeiostream
usingnamespacestd;
intmain(intargc,char*argv[])
Py_Initialize();
if(!Py_IsInitialized())
cout"Initializefailed!"endl;
return0;
PyObject*pModule=NULL;
PyObject*pFunc;
PyRun_SimpleString("importos");
PyRun_SimpleString("os.system('pwd')");
pModule=PyImport_ImportModule("pysplit");
if(pModule==NULL)
cout"ModuleNotFound!"endl;
//pFunc=PyObject_GetAttrString(pModule,"sp");
//PyObject*args=Py_BuildValue("s","TestStringHelloEveryOne!");
//PyObject*pRet=PyObject_CallObject(pFunc,args);
stringcList[10];
//PyArg_Parse(pRet,"[items]",cList);
cout"res:"cListendl;
Py_Finalize();
return0;
}
對(duì)應(yīng)的Python模塊的內(nèi)容為:
#pysplit.py
defsp(string):
returnstring.split()
這是一個(gè)非常簡(jiǎn)單的函數(shù),但是我們?cè)谡{(diào)用的時(shí)候就直接返回了一個(gè)錯(cuò)誤:
dechin@ubuntu2004:~/projects/gitlab/dechin/$g++-ocpycp.cpp-lm-std=c++11-I/usr/include/python3.9/-lpython3.9./cpy
['pysplit.py','cpy','cp.cpp']
ModuleNotFound!
res:0x7ffc622ae900
這個(gè)錯(cuò)誤是說,找不到pysplit這個(gè)模塊。但是我們同時(shí)借助于PyRun_SimpleString調(diào)用了Python中的os庫,執(zhí)行了一個(gè)查看路徑和當(dāng)前路徑下文件的功能,我們發(fā)現(xiàn)這個(gè)C++文件和需要引入的pysplit.py其實(shí)是在同一個(gè)路徑下的,這就很奇怪了沒有導(dǎo)入成功。
第二次嘗試
經(jīng)過一番的資料查詢,最后發(fā)現(xiàn),即使是在相同的路徑下,也需要通過Python的sys將當(dāng)前目錄添加到系統(tǒng)路徑中,才能夠識(shí)別到這個(gè)模塊,同樣也是使用PyRun_SimpleString的函數(shù):
//cp.cpp
#includePython.h
#includeiostream
usingnamespacestd;
intmain(intargc,char*argv[])
Py_Initialize();
if(!Py_IsInitialized())
cout"Initializefailed!"endl;
return0;
PyObject*pModule=NULL;
PyObject*pFunc;
PyRun_SimpleString("importsys");
PyRun_SimpleString("sys.path.append('./')");
pModule=PyImport_ImportModule("pysplit");
if(pModule==NULL)
cout"ModuleNotFound!"endl;
pFunc=PyObject_GetAttrString(pModule,"sp");
PyObject*args=Py_BuildValue("s","TestStringHelloEveryOne!");
PyObject*pRet=PyObject_CallObject(pFunc,args);
stringcList[10];
//PyArg_Parse(pRet,"[items]",cList);
cout"res:"cListendl;
Py_Finalize();
return0;
}
這個(gè)也可以理解,Python中的函數(shù)調(diào)用,輸入?yún)?shù)都被打包成了一個(gè)tuple格式,比如**args,而類似**kwargs則是打包成一個(gè)字典格式,類似的功能在這篇博客中有所介紹。
第三次嘗試
上面的問題,在StackOverFlow上有一個(gè)類似的情況,有一個(gè)回答解決了這個(gè)問題,解決方案是,用PyObject_CallFunctionObjArgs來替代PyObject_CallObject去實(shí)現(xiàn)函數(shù)調(diào)用命令,相關(guān)代碼如下:
//cp.cpp
#includePython.h
#includeiostream
usingnamespacestd;
intmain(intargc,char*argv[])
Py_Initialize();
if(!Py_IsInitialized())
cout"Initializefailed!"endl;
return0;
PyObject*pModule=NULL;
PyObject*pFunc;
PyRun_SimpleString("importsys");
PyRun_SimpleString("sys.path.append('./')");
pModule=PyImport_ImportModule("pysplit");
if(pModule==NULL)
cout"ModuleNotFound!"endl;
pFunc=PyObject_GetAttrString(pModule,"sp");
PyObject*args=Py_BuildValue("s","TestStringHelloEveryOne!");
PyObject*pRet=PyObject_CallFunctionObjArgs(pFunc,args,NULL);
intsize=PyList_Size(p
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 新任經(jīng)理發(fā)言稿
- 家長(zhǎng)會(huì) 德育發(fā)言稿
- 時(shí)間的腳印白板課件
- 宇通客車現(xiàn)金流量質(zhì)量分析
- 秋天的思念課件大綱
- 2025版房地產(chǎn)精裝修施工合同包含建筑節(jié)能認(rèn)證服務(wù)
- 二零二五年新能源企業(yè)勞動(dòng)保密及保密義務(wù)協(xié)議
- 2025版車輛買賣合同擔(dān)保及車輛改裝服務(wù)范本
- 2025版花卉進(jìn)出口貿(mào)易合同
- 2025版某局信息化項(xiàng)目勞務(wù)分包結(jié)算規(guī)范合同
- GB/T 25751-2010壓縮氣彈簧技術(shù)條件
- GB/T 19137-2003農(nóng)藥低溫穩(wěn)定性測(cè)定方法
- 《中風(fēng)的中醫(yī)辨證論治(論文)4000字》
- 學(xué)院績(jī)效考核辦法和考核細(xì)則
- DBJ41∕T 225-2019 建筑施工斜拉懸挑式卸料平臺(tái)安全技術(shù)標(biāo)準(zhǔn)-(高清版)
- 宗族祠堂的當(dāng)代文化價(jià)值
- 網(wǎng)店開設(shè)與運(yùn)營(yíng)實(shí)戰(zhàn)教程教學(xué)ppt課件(完整版)
- GB∕T 3185-2016 氧化鋅(間接法)
- 南京南站明挖隧道施工方案
- DB37∕T 5023-2014 非透明幕墻建筑外保溫系統(tǒng)應(yīng)用技術(shù)規(guī)程
- 電網(wǎng)調(diào)度自動(dòng)化維護(hù)員崗位培訓(xùn)題庫簡(jiǎn)答題
評(píng)論
0/150
提交評(píng)論