我有一个在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模块直接替换,它可以在后台自动执行大多数必需的管道。
ctypes
示例:假设您在Linux上的Python中,已经安装了Wine,并且想要调用msvcrt.dll(Microsoft C运行时库)。您可以执行以下操作:
msvcrt.dll
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))
源代码(LGPL) ,PyPI软件包和文档。它的边缘仍然有些粗糙(即Alpha和不安全),但是它确实可以处理大多数类型的参数(包括指针)。
您可以使用XMLRPC客户端和Python内置的stdlib服务器来执行所需的操作。只需使您的Wine- Python将所需的函数作为XMLRPC方法公开,并从任何其他Python程序对该进程进行进程间调用即可。
它也适用于从CPython调用Jython或IronPython中运行的函数,也可以跨Python2和Python3调用- 模块文档本身包含的示例应该足够了。只需检查以下文档即可:https ://docs.python.org/2/ library / xmlrpclib.html
如果您需要调用在客户端或服务器站点上异步进行响应,以响应多个进程,则可以找到其他框架来构建调用- Celery还应跨多个不同的Python工作,同时保持调用兼容性,在性能方面肯定足够了。