易語言調用Python的一種方法(通過Socket通信方式)*
問題的産生
很多熟悉E語言的朋友大多是因為其開發效率高,函數使用友善。然而Python在資料處理,人工智能等領域的優勢是易語言無法比拟的。python的pyqt庫開發效率和打包體積尚不如易語言。把二者結合能極大提高開發效率和擴充開發能力。
本文通過建立Socket通信方式實作E語言和python的連接配接,E語言作為服務端,python作為用戶端,E語言程式通過發送固定格式的資料,python收到之後執行函數,最後發送資料傳回給E語言,實作調用。
易語言代碼(服務端)
在這裡插入代碼片片
.支援庫 HPSocket_E
.支援庫 spec
.程式集 視窗程式集_啟動視窗
.程式集變量 監聽器對象句柄, 整數型
.程式集變量 Socket對象句柄, 整數型
.程式集變量 TCP服務端, TCP服務端
.程式集變量 pythonID, 整數型
.子程式 _按鈕1_被單擊
.局部變量 a, 整數型
TCP服務端.發送資料 (Socket對象句柄, pythonID, “function1|” + 到文本 (a))
.子程式 __啟動視窗_将被銷毀
' 銷毀 Socket 對象
TCP服務端.銷毀監聽環境 (Socket對象句柄, 假)
Socket對象句柄 = 0
' 銷毀監聽器對象
TCP服務端.銷毀初始環境 (監聽器對象句柄)
監聽器對象句柄 = 0
.子程式 __啟動視窗_建立完畢
.局部變量 szBindAddress, 文本型
監聽器對象句柄 = TCP服務端.建立初始環境 ()
調試輸出 (監聽器對象句柄)
Socket對象句柄 = TCP服務端.建立監聽環境 (監聽器對象句柄, 假)
調試輸出 (Socket對象句柄)
TCP服務端.設定回調事件 (監聽器對象句柄, , &客戶進入, , , &資料到達, , )
szBindAddress = “0.0.0.0”
.如果 (TCP服務端.啟動 (Socket對象句柄, szBindAddress, 54321))
調試輸出 (“$ Server Start OK --> (” + szBindAddress + “ : 54321)”)
.否則
調試輸出 (“$ Server Start Fail --> ”)
.如果結束
.子程式 客戶進入, 整數型, , 客戶進入
.參數 pSender, 整數型
.參數 dwConnID, 整數型
.參數 soClient, 整數型
pythonID = dwConnID
調試輸出 (“客戶進入!”, pSender, soClient)
傳回 (#事件通知_成功)
.子程式 _按鈕2_被單擊
TCP服務端.發送資料 (Socket對象句柄, pythonID, “function2|2”)
.子程式 資料到達, 整數型, , 資料到達
.參數 pSender, 整數型
.參數 dwConnID, 整數型
.參數 pData, 整數型, , 資料指針 需通過指針到位元組集擷取資料
.參數 iLength, 整數型
調試輸出 (指針到文本 (pData))
傳回 (#事件通知_成功)
Python代碼(用戶端)
在這裡插入代碼片
```from concurrent.futures import ThreadPoolExecutor
from socket import *
import pyefun as efun
#全局指派--------------
IP = '127.0.0.1'
SERVER_PORT = 54321
BUFLEN = 1024
Socket_用戶端 = socket(AF_INET, SOCK_STREAM)
Socket_用戶端.connect((IP, SERVER_PORT))
Arr=[None for i in range(32)]
#全局指派--------------
def 傳回結果到易語言(c_Socket,c_content):
c_Socket.send(c_content)
# 定義功能函數---------------------------------------
def function1(a):
efun.延時(2)
print(a.encode('utf-8'))
傳回結果到易語言(Socket_用戶端, a.encode('utf-8'))
return None
def function2(a):
efun.延時(2)
print(a)
傳回結果到易語言(Socket_用戶端, a.encode('utf-8'))
return None
def function3(a):
efun.延時(0.1)
print(a)
傳回結果到易語言(Socket_用戶端, a.encode('utf-8'))
return None
# 定義功能函數---------------------------------------
pool = ThreadPoolExecutor(max_workers=50)# 建立一個包含n條線程的線程池
def 投遞任務(c_FuncName,c_value):
BigBreak=False
while True:
for i in range(32):
if Arr[i] != None:
if Arr[i].done() == True:
Arr[i] = None
if Arr[i] == None:
#自己改動區域,添加函數時候在此修改函數名——————————————————
if c_FuncName=="function1":
Arr[i] = pool.submit(function1, c_value)
elif c_FuncName=="function2":
Arr[i] = pool.submit(function2, c_value)
elif c_FuncName == "function3":
Arr[i] = pool.submit(function3, c_value)
# 自己改動區域,添加函數時候在此修改函數名——————————————————
BigBreak = True
break
if BigBreak == True:
BigBreak = False
break
print(c_value)
efun.延時(0.1)
if __name__ == '__main__':#主函數
while True:
接收資料 = Socket_用戶端.recv(BUFLEN).decode('utf-8') # 這裡是取回資料的意思
back_list=efun.分割文本(接收資料,"|",2)
# print(back_list[0],back_list[1])
投遞任務(back_list[0], back_list[1])
back_list[0]=""
back_list[1]=""
efun.延時(0.01)
pool.shutdown()
代碼邏輯
通過這種通信方式,如果簡單的執行python的函數,勢必隻能進行同步操作,是以在python中加入了線程池(50)條線程,可以達到異步執行函數的效果,最大限度的模拟真實調用。
遇到問題
在執行一般程式時,經過測試這種方式可以進行調用,并且穩定性很好,但是當線程池的所有線程全部占用時候,會出現python傳回給E語言資料不一緻的問題,這個問題暫時沒有找到答案,如果有朋友解決了記得評論
所用工具
HP-Socket支援庫5.4版本 百度能找到 https://www.eyuyan.la/post/11777.html
Python的pyefun庫 、socket 庫 自行pip