我有一个在Linux上运行的Python(3)脚本,称为主脚本,它必须从专有DLL调用例程。到目前为止,我使用以下结构用Wine解决了这个问题:
# Main script running on Linux
import subprocess
# [...]
subprocess.Popen('echo "python dll_call.py %s" | wine cmd &' % options, shell = True)
# [...]
脚本 dll_call.py 由安装在Wine下的Windows Python(3)解释器执行。它将返回值转储到一个文件中,然后由等待的主脚本拾取。如果我必须连续几次这样做,那么它并不完全可靠且令人痛苦。
我想启动脚本 dll_call.py 一次,提供某种类型的简单服务器,它应该以某种方式公开所需的例程。在一天结束时,我想让主脚本看起来像这样:
# Main script running on Linux
import subprocess
# [...]
subprocess.Popen('echo "python dll_call_server.py" | wine cmd &', shell = True)
# [...]
return_values = call_into_dll(options)
如何最好地实施(如果需要速度且安全性不是问题)?
感谢@jsbueno和@AustinHastings提供的答案和建议。
对于那些有类似问题的人:受到上述答案的启发,我写了一个小的Python模块,用于在Linux上从Python调用Windows DLL。它基于IPC在常规Linux / Unix Python进程和基于Wine的Python进程之间。因为我在太多不同的用例/场景中需要它,所以我将其设计为“通用”ctypes
module直接替换,它在后台自动完成大部分所需的管道。
示例:假设您在Linux上使用Python,安装了Wine,并且想要调用msvcrt.dll
(Microsoft C运行时库)。您可以执行以下操作:
import zugbruecke as ctypes
dll_pow = ctypes.cdll.msvcrt.pow
dll_pow.argtypes = (ctypes.c_double, ctypes.c_double)
dll_pow.restype = ctypes.c_double
print('You should expect "1024.0" to show up here: "%.1f".' % dll_pow(2.0, 10.0))
Source code (LGPL),PyPI package& documentation 即可。它在边缘仍然有点粗糙(即alpha和不安全),但它确实处理大多数类型的参数(包括指针)。
答案 0 :(得分:2)
您可以使用XMLRPC客户端和服务器内置Python的stdlib来执行您想要的操作。只需让Wine-Python将所需的函数公开为XMLRPC方法,并从任何其他Python程序进行进程间调用。
它也适用于从CPython调用Jython或IronPython中运行的函数,以及Python2和Python3中的函数 - 模块文档中包含的示例本身就足够了。只需检查文档:https://docs.python.org/2/library/xmlrpclib.html
如果您需要在客户端调用异步,或者服务器站点响应多个进程,您可以找到构建调用的其他框架--Celery也应该在保留多个不同的Pythons的同时保留呼叫兼容性,这在性能方面肯定是足够的。
答案 1 :(得分:1)
您希望在两个进程之间进行通信,其中一个进程在WINE引擎的控制下被遮挡。
我首先想到的是使用非常解耦形式的IPC。紧耦合和WINE之类的东西可能会出现太多问题。
最后,对于刚接触这类东西的人来说,如何才能轻松实现这一目标?
显而易见的答案是设置Web服务器。有很多教程使用Python中的大量软件包来响应HTTP请求,并生成HTTP请求。
因此,在您的WINE进程中设置一个小的HTTP响应器,听一些非标准端口(不是8080或80),并将请求转换为对DLL的调用。如果你聪明,你会将Web请求(http://localhost:108000/functionname?arg1=foo&arg2=bar)解释为可能不同的DLL调用。
另一方面,在非WINE代码中创建一个HTTP客户端并向服务器发出请求。