雖然python開發效率很高,但作為腳本語言,其性能不高,所以為了兼顧開發效率和性能,通常把性能要求高的模組用c或c++來實現或者在c或c++中運行python腳本來處理邏輯,前者通常是python中一些模組的實現方式,後者服務端程式(實現業務擴展或是Plugin功能)和遊戲開發(腳本只處理邏輯)中比較常見。本文主要介紹透過在c中運行python腳本來實現python與c的相互調用,並透過c和python腳本設定同一段記憶體區域為例子來講解。
前言
最近因為工作的需要,在考慮基於udp做一個用於網遊戰鬥中的資料同步協議,為了前期測試數據,決定先做一個外部的代理tunnel,原理是在server端和client端分別建立網絡轉發proxy,即原來的C/S連接改為兩個proxy之間數據快速傳輸。因為udp函式庫是用C++寫的程式碼,在測試資料的時候需要不斷地修改參數,重新編譯,修改輸出統計資料製表等,不勝其煩,最後決定導出介面由python腳本來進行邏輯呼叫。下面話不多說,來一起看看詳細的介紹:
# 為了在c中運行python腳本,需要在程式連結的時候將python虛擬機庫連結進去,python虛擬機庫是python安裝目錄下libs中的python27.lib文件,至於怎樣將庫鏈接進程序中可以自己google下。由於在c中使用了python的一些方法和資料結構,所以需要將python安裝目錄下的include目錄加入到專案include目錄中。好了,需要準備的就是這些,然後就可以開始實作一個設定記憶體區域的例子了。
C/C++匯出到python有多種方法,根據不同的需求,可以使用下面不同的方式:
1、ctypes綁定。 ctypes就包含在萬能的python標準庫模組裡面,它可以運行時載入動態連結庫(dll,so),在CPython 2.x/3.x和PyPy上都支援。這種方式好處就是不用針對性地用python api寫導出函數,可以直接載入動態連結函式庫的符號表,在python中就可以直接呼叫了。
2、第三方的python binding。例子有boost-python,實作方式是工具自動化用Python/C api產生一系列C++ wrapper函數。特別適用於大型的函式庫或引擎匯出到python。
3、手動寫python binding函數。如果對Python C api熟悉的話,這種方式應該是最靈活的,讀一遍API文件就可以使用。理論上效率應該是最好的,但對於我這種python初學者,可能需要花上不少時間。
以之前折騰C函數匯出到Lua腳本的經歷,本來以為要先研究一番python c api,再搞上半天才能搞定。後面發現python標準函式庫模組的ctypes已經非常強大,雖然效能應該是三種方式裡面最差的,但在這個最高60fps的tunnel裡面,C/Python介面邊界呼叫的損耗先忽略。跟其他兩種方式設計不一樣的是,ctypes採用的是非入侵式呼叫介面的方式,不需要修改原來的C介面或是寫一些綁定程式碼,直接對編譯出來的動態函式庫進行呼叫。 ctypes使用過程也是非常愉悅的。
下面介紹下ctypes的使用:
1、載入DLL動態連結函式庫
這裡要注意區分動態連結函式庫函數是使用cdecl還是stdcall的呼叫約定,分別使用cdll或windll載入動態函式庫。
例如:
# 加载udp库函数 udp_server = cdll.LoadLibrary("./udp_server.so") init_udp_server = udp_server.init_udp_server destroy_udp_server = udp_server.destroy_udp_server update_udp_server = udp_server.update_udp_server SendMsg = udp_server.SendMsg SetConnectCallback = udp_server.SetConnectCallback SetDisconnectCallback = udp_server.SetDisconnectCallback SetTimeoutCallback = udp_server.SetTimeoutCallback SetRecvCallback = udp_server.SetRecvCallback
2、資料類型映射
除了ctypes定義的基本數據類型(c_char, c_int, c_double等),也能使用pointer函數轉換成指標型別。對於要導出的網路庫,設定回呼函數是必不可少的,在C++庫裡面,回呼函數是透過設定一個函數指標完成的,ctypes同樣支援函數指標的聲明。如:recv_cb = CFUNCTYPE( None, c_char_p, c_int )
,表示一個回傳值為void,參數為char*和int型別的回呼函數。
def init(self, port, ip="127.0.0.1"): self._port = port self._ip = ip self._clients = {} self.c_connect_cb = connect_cb(self.server_connect) self.c_disconnect_cb = disconnect_cb(self.server_disconnect) self.c_timeout_cb = timeout_cb(self.server_timeout) self.c_recv_cb = recv_cb(self.server_recv) def create(self): if self._port: if init_udp_server(self._ip, self._port) == 0: print "server listen %s:%d" % (self._ip, self._port) SetConnectCallback( self.c_connect_cb ) SetDisconnectCallback( self.c_disconnect_cb ) SetTimeoutCallback( self.c_timeout_cb ) SetRecvCallback( self.c_recv_cb ) return True print "[error] init_udp_server error", self._ip, self._port return False
綁定回呼參數需要注意的是,綁定的回呼函數需要保存為成員變數(上面的寫法),目的是避免python垃圾回收導致回呼函數變成野指針。這算是一個小小的坑吧。基本上一個小小的函式庫也就用到這些功能。
以上是python與C互相調用的詳細介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

pythonisehybridmodeLofCompilation和interpretation:1)thepythoninterpretercompilesourcecececodeintoplatform- interpententbybytecode.2)thepythonvirtualmachine(pvm)thenexecutecutestestestestestesthisbytecode,ballancingEaseofuseEfuseWithPerformance。

pythonisbothinterpretedAndCompiled.1)它的compiledTobyTecodeForportabilityAcrosplatforms.2)bytecodeisthenInterpreted,允許fordingfordforderynamictynamictymictymictymictyandrapiddefupment,儘管Ititmaybeslowerthananeflowerthanancompiledcompiledlanguages。

在您的知識之際,而foroopsareideal insinAdvance中,而WhileLoopSareBetterForsituations則youneedtoloopuntilaconditionismet

ForboopSareSusedwhenthentheneMberofiterationsiskNownInAdvance,而WhileLoopSareSareDestrationsDepportonAcondition.1)ForloopSareIdealForiteratingOverSequencesLikelistSorarrays.2)whileLeleLooleSuitableApeableableableableableableforscenarioscenarioswhereTheLeTheLeTheLeTeLoopContinusunuesuntilaspecificiccificcificCondond

pythonisnotpuroly interpred; itosisehybridablectofbytecodecompilationandruntimeinterpretation.1)PythonCompiLessourceceCeceDintobyTecode,whitsthenexecececected bytybytybythepythepythepythonvirtirtualmachine(pvm).2)

concatenateListSinpythonWithTheSamelements,使用:1)operatoTotakeEpduplicates,2)asettoremavelemavphicates,or3)listcompreanspherensionforcontroloverduplicates,每個methodhasdhasdifferentperferentperferentperforentperforentperforentperfornceandordorimplications。

pythonisanterpretedlanguage,offeringosofuseandflexibilitybutfacingperformancelanceLimitationsInCricapplications.1)drightingedlanguageslikeLikeLikeLikeLikeLikeLikeLikeThonexecuteline-by-line,允許ImmediaMediaMediaMediaMediaMediateFeedBackAndBackAndRapidPrototypiD.2)compiledLanguagesLanguagesLagagesLikagesLikec/c thresst

Useforloopswhenthenumberofiterationsisknowninadvance,andwhileloopswheniterationsdependonacondition.1)Forloopsareidealforsequenceslikelistsorranges.2)Whileloopssuitscenarioswheretheloopcontinuesuntilaspecificconditionismet,usefulforuserinputsoralgorit


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

Dreamweaver CS6
視覺化網頁開發工具

Atom編輯器mac版下載
最受歡迎的的開源編輯器

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

Dreamweaver Mac版
視覺化網頁開發工具

禪工作室 13.0.1
強大的PHP整合開發環境