目錄
1.背景介紹與程式設計環境
2.完整例項演示
3.問題集錦
4.總結
5.參考鏈結
背景介紹:
近年來,python語言憑藉著自身語言的簡單易學(相對於其他程式語言來說)及其功能強大的函式庫(還有其他優點),受到許多程式設計愛好者的青睞,同時十分廣泛的用於人工智慧演算法程式設計中。c/c++語言是基礎的程式語言,可以實現與核心的互動,提高程式設計質量。c/c++與python各有其程式設計優點。python語言開發效率高,平時需要使用python做一些任務指令碼,指令碼裡面主要包含了任務流程所需要命令執行和返回序列,而這些命令最終是需要到c/c++編寫的程式**中執行的,所以需要在c/c++中呼叫和解析python指令碼。
最近專案中遇到需要用c++呼叫python**的情況,在網上搜尋後發現中文資料比較少。因此藉此機會一邊學習一邊整理成文件,方便後續查閱。
程式設計環境:
linux作業系統
python3.5
c呼叫python指令碼程式:
//c_call_python.cpp
#include int main()
//第三步:查詢對應math_test.py中的def mainfunc(a,b)函式
pfunction = pyobject_getattrstring(pmodule, "mainfunc");
if (!pfunction)
//第四步:新建python中的tuple物件(構建引數)
pargs = pytuple_new(2);
//pytuple_setitem(pargs, 0, py_buildvalue(""));
pytuple_setitem(pargs, 0, py_buildvalue("i", a));
pytuple_setitem(pargs, 1, py_buildvalue("i", b));
//第五步:呼叫函式
pretvalue=pyobject_callobject(pfunction, pargs);
//第六步:清空pyobject
py_decref(pmodule);
py_decref(pfunction);
py_decref(pargs);
py_decref(pretvalue);
if (!pmodule)
//第七步:很關鍵的一步,如果是多次匯入pyimport_importmodule模組
//只有最後一步才呼叫py_finalize(),此時python全域性變數一直儲存著
py_finalize();
//方便檢視
while (1);
return 0;
}
可執行python指令碼1:math_util.py
#!/usr/bin/python
import sys,codecs
import time
import other as oth
def add_func(a,b):
return (a+b)
def sub_func(a,b):
return (a-b)
def mainfunc(a,b):
starttime=time.time()
oth.funx2(a)
print("success!")
result_1=add_func(a,b)
result_2=sub_func(a,b)
print("a+b= ",result_1," a-b= ",result_2)
endtime=time.time()
print("spend time: ",endtime-starttime)
def main():
mainfunc(2,6)
if __name__ == '__main__':
main()
可執行python指令碼2:other.py
#other.py
import numpy as np
def funx2(a):
data = [[1,2],[3,4],[5,6]]
x = np.array(data)
print(x)
print("call funx2 numpy2")
return a*2
編譯命令如下:
gcc $(python3.5-config --ldflags) test3.c -o test3.out
如上提供的**是可正確執行的。正確執行的結果如下圖所示:
其中,在c呼叫python指令碼程式中,python_initialize()主要是初始化python直譯器。
py_******string("import sys")相當於在python中的import sys語句。
py_importmodule("helloworld")是利用匯入檔案函式將helloworld.py函式匯入。
pyobject_getattrstring(pmodule, "hello")是在pyton引用模組helloworld.py中查詢hello函式。
接著呼叫pyeval_callobject(pfunc, null)呼叫hello函式。最後是清理python環境釋放資源。
問題1:python指令碼本身存在錯誤
出現如上問題的原因是python指令碼本身存在錯誤,解決方案就是要確保你的python指令碼可以執行。
問題2:python.h:沒有那個檔案與目錄
出現如上問題的原因是找不到python.**件
此時我的呼叫的標頭檔案如上圖所示,一般來說該標頭檔案都會存在,還有一方面原因是系統中裝有多個的python版本,導致程式無法判斷,所以需要指定具體版本,如下圖所示。當然,如果你只安裝了一種版本的python,可能就不會出現該問題。
問題3.編譯命令導致錯誤問題
編譯命令有很多種形式,比如說
有時會因為編譯產生一些錯誤,具體原因筆者還不能給出明確解釋(望賜教)。在網上查詢的一通,嘗試了各種編譯指令,最後使用如上文中所示編譯指令成功編譯執行。
問題4.呼叫第三方庫時出現的問題
對於純python程式而言,絕大部分的python自帶庫是可以正常呼叫。如果python程式中包含了其他第三方庫,則呼叫極可能出錯,且不易查明原因。
python字典小白式講解!新手必看
python字典可儲存任意型別物件,如字串 數字 元組 優點 取值方便,速度快 1,建立字典 字典由鍵 key 和對應值 value 成對組成。字典也被稱作關聯陣列或雜湊表。基本語法如下 每個鍵與值用冒號隔開 每對用逗號,每對用逗號分割,整體放在花括號中 鍵必須獨一無二,但值則不必。值可以取任何資料...
新手學PHP必看
1.概要 學習任何語言都需要多看 多想 多寫 多問!寫程式設計是一種熟能生巧的東西!學習php也一樣,因為知識就那麼多,你看多了就會覺得怎麼都一樣。程式設計師就是炒冷飯的,一遍又一遍。多敲幾遍就可以閉著眼睛寫了,所以企業招聘都會問你寫過多少行 的!程式設計師最忌諱浮躁,有時候發現一段程式完全找不出錯...
新手學習Docker必看
1.為什麼要學docker 答 避免一種情況 我的機器上可以執行,為什麼你的不可以?很多時候,我們想把自己的程式拿給別人執行,別人往往直接拷貝過來是不可以直接用的,甚至怎麼改 怎麼修改環境都用不了,那怎麼辦?docker就是為了解決這個尷尬而出現的。2.docker的作用 答 a.解決執行環境不一致...