将数据从Python传输到Windows中的另一个应用程序的最佳方法是什么?

问题描述 投票:0回答:5

我正在与 .Net (C++) 团队一起开发一个应用程序,并提供一个 COM 接口来与 python 和其他语言交互。

我们发现通过 COM 推送数据非常慢。

我考虑了几种替代方案:

  • 将数据转储到文件并通过 com 发送文件路径
  • 通过 mmap 共享内存?
  • 直接通过套接字传输数据?

根据您的经验,传递数据的最佳方式是什么?

python winapi com data-transfer
5个回答
9
投票

在 Windows 进程间通信机制中,我们使用 windows 命名管道 获得了积极的经验。 使用 Windows 重叠 IO 和来自

pywin32
win32pipe 模块。

您可以在《Win32 上的 Python 编程》一书中了解有关 win32 和 python 的更多信息。 发送部分只需写入

r'\\.\pipe\mypipe'

即可。


侦听器 (

ovpipe

) 对象持有事件句柄,等待可能包含其他事件的消息涉及调用

win32event.WaitForMultipleObjects

rc = win32event.WaitForMultipleObjects( eventlist, # Objects to wait for. 0, # Wait for one object timeout) # timeout in milli-seconds.

这是Python重叠监听器类的一部分:

import win32event import pywintypes import win32file import win32pipe class ovpipe: "Overlapped I/O named pipe class" def __init__(self): self.over=pywintypes.OVERLAPPED() evt=win32event.CreateEvent(None,1,0,None) self.over.hEvent=evt self.pname='mypipe' self.hpipe = win32pipe.CreateNamedPipe( r'\\.\pipe\mypipe', # pipe name win32pipe.PIPE_ACCESS_DUPLEX| # read/write access win32file.FILE_FLAG_OVERLAPPED, win32pipe.PIPE_TYPE_MESSAGE| # message-type pipe win32pipe.PIPE_WAIT, # blocking mode 1, # number of instances 512, # output buffer size 512, # input buffer size 2000, # client time-out None) # no security attributes self.buffer = win32file.AllocateReadBuffer(512) self.state='noconnected' self.chstate() def execmsg(self): "Translate the received message" pass def chstate(self): "Change the state of the pipe depending on current state" if self.state=='noconnected': win32pipe.ConnectNamedPipe(self.hpipe,self.over) self.state='connectwait' return -6 elif self.state=='connectwait': j,self.strbuf=win32file.ReadFile(self.hpipe,self.buffer,self.over) self.state='readwait' return -6 elif self.state=='readwait': size=win32file.GetOverlappedResult(self.hpipe,self.over,1) self.msg=self.strbuf[:size] ret=self.execmsg() self.state = 'noconnected' win32pipe.DisconnectNamedPipe(self.hpipe) return ret



2
投票

作为一般规则,像 COM 这样的专有协议/架构带来的限制多于其带来的好处。这就是开放规范首先出现的原因。

HTH

命名管道上的

2
投票


0
投票

哦,如果你这样做,我相信很多人会对结果感兴趣。


0
投票

import multiprocessing import win32event import pywintypes import win32file import win32pipe import client class ovpipe: "Overlapped I/O named pipe class" def __init__(self): self.over = pywintypes.OVERLAPPED() evt = win32event.CreateEvent(None, 1, 0, None) self.over.hEvent = evt self.pname = 'mypipe' self.hpipe = win32pipe.CreateNamedPipe( r'\\.\pipe\mypipe', # pipe name win32pipe.PIPE_ACCESS_DUPLEX | # read/write access win32file.FILE_FLAG_OVERLAPPED, win32pipe.PIPE_TYPE_MESSAGE | # message-type pipe win32pipe.PIPE_WAIT, # blocking mode 2, # number of instances 512, # output buffer size 512, # input buffer size 2000, # client time-out None) # no security attributes self.buffer = win32file.AllocateReadBuffer(512) self.state = 'noconnected' self.chstate() def execmsg(self): "Translate the received message" return bytes(self.msg).decode() def chstate(self): "Change the state of the pipe depending on current state" if self.state == 'noconnected': win32pipe.ConnectNamedPipe(self.hpipe, self.over) self.state = 'connectwait' return -6 elif self.state == 'connectwait': j, self.strbuf = win32file.ReadFile(self.hpipe, self.buffer, self.over) self.state = 'readwait' return -6 elif self.state == 'readwait': size = win32file.GetOverlappedResult(self.hpipe, self.over, 1) self.msg = self.strbuf[:size] ret = self.execmsg() self.state = 'noconnected' win32file.WriteFile(self.hpipe, b'Hello, client!') win32pipe.DisconnectNamedPipe(self.hpipe) return ret def client_main(): PIPE_NAME = r'\\.\pipe\MyPipe' # open a named pipe for writing pipe = win32file.CreateFile( PIPE_NAME, win32file.GENERIC_READ | win32file.GENERIC_WRITE, 0, # no sharing None, # default security attributes win32file.OPEN_EXISTING, 0, # default attributes None # no template file ) # send data to the server data = b'Hello, server!' win32file.WriteFile(pipe, data) print(f'Sent Message to Server: \"{data.decode()}\". Waiting for response') # receive a response from the server response = win32file.ReadFile(pipe, 65536) print(f'Received response from server: {response}') # close the named pipe win32file.CloseHandle(pipe) def main(): ov = ovpipe() rc = win32event.WaitForMultipleObjects( [ov.over.hEvent], # Objects to wait for. 0, # Wait for one object 500) # timeout in milli-seconds. print(rc) p = multiprocessing.Process(target=client_main, daemon=True) p.start() for _ in range(5): rc = win32event.WaitForMultipleObjects( [ov.over.hEvent], # Objects to wait for. 0, # Wait for one object 2000) # timeout in milli-seconds. print(rc) win32event.ResetEvent(ov.over.hEvent) if rc == 0: res = ov.chstate() if type(res) is str: print(f"Received message from client: {res}") break p.join(10000) if __name__ == '__main__': main()

© www.soinside.com 2019 - 2024. All rights reserved.