麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > Python > 正文

python和C的互相調用

2019-11-11 05:42:46
字體:
來源:轉載
供稿:網友
最近在考慮基于udp做一個用于網游戰斗中的數據同步協議,為了前期測試數據,決定先做一個外部的代理tunnel,原理是在server端和client端分別建立網絡轉發PRoxy,即原來的C/S連接改為兩個proxy之間數據快速傳輸。因為udp庫是用C++寫的代碼,在測試數據的時候需要不斷地修改參數,重新編譯,修改輸出統計數據制表等,不勝其煩,最終決定導出接口由python腳本來進行邏輯調用。C/C++導出到python有多種方法,根據不同的需求,可以使用下面不同的方式:ctypes綁定。ctypes就包含在萬能的python標準庫模塊里面,它可以運行時載入動態鏈接庫(dll,so),在CPython 2.x/3.x和PyPy上都支持。這種方式好處就是不用針對性地用python api寫導出函數,可以直接加載動態鏈接庫的符號表,在python中就可以直接調用了。 第三方的python binding。例子有boost-python,實現方式是工具自動化用Python/C api生成一系列C++ wrapper函數。特別適用于大型的庫或引擎導出到python。手動寫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_serverdestroy_udp_server = udp_server.destroy_udp_serverupdate_udp_server = udp_server.update_udp_serverSendMsg = udp_server.SendMsgSetConnectCallback = udp_server.SetConnectCallbackSetDisconnectCallback = udp_server.SetDisconnectCallbackSetTimeoutCallback = udp_server.SetTimeoutCallbackSetRecvCallback = udp_server.SetRecvCallback2. 數據類型映射除了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垃圾回收導致回調函數變成野指針。這算是一個小小的坑吧。基本上一個小小的庫也就用到這些功能。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 精品国产一级毛片 | 久久久经典视频 | 国产午夜精品久久久久婷 | 国产一精品一av一免费爽爽 | 天堂精品久久 | 免费毛片在线 | 91九色视频观看 | 久久国产成人精品国产成人亚洲 | 久久精品99国产国产精 | 一边吃奶一边插下面 | 国产亚洲精彩视频 | 日韩av在线资源 | 综合精品一区 | www.9191.com| 中文欧美日韩 | 少妇一级淫片高潮流水电影 | 国产品久久 | 久久久久久麻豆 | 亚洲午夜影院在线观看 | 国产三级午夜理伦三级 | 福利在线免费视频 | 亚洲免费毛片基地 | av在线免费观看网站 | 久久成人福利 | 成人在线观看一区 | 成年免费视频黄网站在线观看 | 成人免费网站在线观看 | 久久久毛片视频 | 性猛交ⅹxxx乱巴西 在线播放中文 | 717影院理论午夜伦八戒秦先生 | 国产99久久精品一区二区 | 免费观看一级欧美大 | 免费看成年人网站 | 看片一区二区三区 | 日韩激情一区二区三区 | 一级裸体视频 | av在线免费电影 | 欧美视频黄色 | 国产精品视频一区二区三区四 | 中文字幕精品一区久久久久 | 色啪综合|