SWIG和Python:创建与任何3.x版本兼容的软件包

mqkwyuun  于 2023-02-17  发布在  Python
关注(0)|答案(2)|浏览(254)

SWIG为Python模块生成两个 Package 层:C Package 器代码和Python Package 器代码。而且,据我所知,两者都不知道Python 3. x(目前是3. 1 - 3. 6)的特定subversion。
但是,在编译代码时,我必须包含特定Python 3.x版本的头文件,其中包含PyConfig.h中的特定库版本,例如3.4:pragma comment(lib,"python34.lib")-这会导致Python包必须在运行时找到并加载python34.dll,而在任何其他版本中加载都将失败。
但是Python 3.x的所有版本都是兼容的,并且只需对生成的.pyd二进制文件进行简单的编辑--用python36.dll替换python34.dll就可以使最终的模块与Python 3.6一起工作。
有没有办法用SWIG创建一个Python 3.x包,它能够搜索并找到系统上安装的任何可用的3.x版本?

cl25kdpy

cl25kdpy1#

您可以“强制”将您的项目链接到python3.lib而不是链接到python3X.lib(其中X是次要版本)。 Package 器将python3.dll作为其导入的一部分,并且python3.dll将转发到python3X.dll
然而,注意你使用的API必须来自Python 3 API的公共集合(我相信从Python 3.2开始,参见下面的参考),如果你需要使用Python 3.2中不存在的API,但是Python 3.3以后的版本中存在,你的SWIG Package 器仍然会链接到次要库。
例如,如果你正在使用从Python 3.3开始就存在的PyUnicode_AsUTF8PyUnicode_AsUTF8AndSize,然后你试图编译Python 3.6和Python 3.7的 Package 器,尽管这些API在两个版本中是通用的,但是它们将作为python36.dllpython37.dll导入的一部分被包括进来。
参考文件:PEP 384

yacmzcpb

yacmzcpb2#

我还尝试构建一个Python 3通用SWIG库,因为我的库的用户可能安装了不同版本的Python 3,目前我需要为每个版本的Python(3.7、3.8、3.9 ......)构建不同的库,这越来越难以维护,并且会让客户感到困惑。
我尝试过定义Py_LIMITED_API,但不幸的是,看起来SWIG使用了完整API中的函数,例如在classobject. h中找到的PyInstanceMethod_New()。
我能够破解SWIG生成的 *_wrap.c文件,以删除对PyInstanceMethod_New的引用(),同样的编译模块现在看起来确实在Python 3.7和Python 3.11中加载了,但这只是一个非常简单的例子,调用了一个C函数,并且没有类。我担心更复杂的C++类库不会以同样的方式工作。如果有人对如何创建通用的Python 3 SWIG Package 库有更多的最新想法,我将非常感激。

相关问题