天天看點

易語言調用Python的一種方法(通過Socket通信方式)易語言調用Python的一種方法(通過Socket通信方式)*問題的産生

易語言調用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的一種方法(通過Socket通信方式)易語言調用Python的一種方法(通過Socket通信方式)*問題的産生

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