易语言调用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