天天看点

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