【问题标题】:SWIG and Python: Create a package compatible with any 3.x versionSWIG 和 Python:创建与任何 3.x 版本兼容的包
【发布时间】:2017-02-15 00:32:54
【问题描述】:

SWIG 为 Python 模块生成两个包装层:C 包装器代码和 Python 包装器代码。而且,据我了解,两者都与 Python 3.x(目前为 3.1-3.6)的特定颠覆无关。

但是,在编译代码时,我必须包含特定 3.x 版本 Python 的标头,其中包括 PyConfig.h 中的特定库版本,例如3.4:pragma comment(lib,"python34.lib") - 这导致 Python 包必须在运行时中查找并加载 python34.dll,并且任何其他版本的加载都会失败。

但是所有 3.x 版本都是兼容的,并且可以对生成的 .pyd 二进制文件进行简单的编辑 - 将 python34.dll 替换为 python36.dll 使得最终模块可以很好地与 Python 3.6 一起使用。

是否有任何方法可以使用 SWIG 创建 Python 3.x 包,以便能够搜索和查找系统上安装的任何可用的 3.x 版本?

【问题讨论】:

  • 鉴于 pragma 来自 PyConfig.h,我认为这更像是 Windows/DLL/Python 的事情,而不是 SWIG 的事情,但这是一个很好的问题。
  • @Flexo 是的,我认为你是对的。但是,我认为可能有一些“棘手”的解决方法。可以删除此编译指示。如果可以使用 LoadLibrary/GetProcAddress 动态加载 Python dll 和函数,那么搜索任何可用的 python3x.dll 二进制文件将很容易。但是鉴于 SWIG 结构,我没有立即看到这样做的方法,它显式链接到 Python
  • 嗨!您对此有所了解吗?
  • 你可以定义Py_LIMITED_API,然后它会链接到python3.lib而不是具体的版本。检查 Python.h 标头

标签: python python-3.x swig


【解决方案1】:

您可以“强制”将您的项目链接到python3.lib,而不是链接到python3X.lib(其中X 是次要版本)。然后包装器将python3.dll 作为其导入的一部分,python3.dll 将转发到python3X.dll

但是,请注意,您使用的 API 需要来自通用的 Python 3 API 集(我相信从 3.2 开始,请参阅下面的参考资料)。如果您需要使用 3.2 上不存在但 3.3 及更高版本存在的 API,您的 SWIG 包装器仍将链接到次要库。

例如,如果您使用从 Python 3.3 开始存在的 PyUnicode_AsUTF8PyUnicode_AsUTF8AndSize,然后您尝试为 3.6 和 3.7 编译您的包装器,尽管这些 API 对于两个版本都是通用的,但它们将被包含为python36.dllpython37.dll 导入的一部分。

参考:PEP 384

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-31
    • 2018-08-29
    • 2022-08-18
    • 2021-03-24
    • 1970-01-01
    • 2015-12-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多