Linux 上的 Python 脚本 运行 如何在 Wine 下调用 Python 脚本 运行 中的例程?

How would a Python script running on Linux call a routine in a Python script running under Wine?

我在 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) 解释器执行。它将 return 值转储到一个文件中,然后由等待的主脚本获取该文件。如果我必须连续几次这样做,它就不太可靠,而且速度慢得令人痛苦。

我想启动脚本 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 模块 用于从 [=51] 调用 Windows DLL =] 在 Linux 上。它基于常规 Linux/Unix Python 进程和基于 Wine 的 Python 进程之间的 IPC。因为我在太多不同的用例/场景中需要它,所以我将它设计为 "generic" 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 和不安全),但它确实可以处理大多数类型的参数(包括指针)。

您想在两个进程之间进行通信,其中一个进程在 WINE 引擎的控制下变得模糊不清。

我在这里的第一个想法是使用 非常 解耦形式的 IPC。紧密耦合和 WINE 之类的东西可能会出错。

最后,如何让刚接触此类内容的人轻松上手?

显而易见的答案是设置网络服务器。 Python 中有大量教程使用大量包来响应 HTTP 请求和生成 HTTP 请求。

因此,在您的 WINE 进程中设置一个小的 HTTP 响应程序,监听一些 non-standard 端口(不是 8080 或 80),并将请求转换为对您的 DLL 的调用。如果您够聪明,您会将 Web 请求 (http://localhost:108000/functionname?arg1=foo&arg2=bar) 解释为可能不同的 DLL 调用。

另一方面,在您的 non-WINE 代码中创建一个 HTTP 客户端并向您的服务器发出请求。

您可以使用 XMLRPC 客户端和服务器 built-in Python 的标准库来执行您想要的操作。只需让您的 Wine-Python 将所需的函数公开为 XMLRPC 方法,然后从任何其他 Python 程序中调用 inter-process 即可。

它也适用于调用 Jython 中的函数 运行 或 CPython 中的 IronPython,也适用于 Python2 和 Python3 -模块文档中包含的示例本身应该是 enough.Just 检查文档:https://docs.python.org/2/library/xmlrpclib.html

如果您需要在客户端异步调用,或者服务器站点响应多个进程,您可以找到其他框架来构建调用——Celery 也应该跨多个不同的 Pythons同时保持调用兼容性,肯定够了performance-wise.